Roadmap › Clean Code, Testing & Best Practices › Module: Readable Code
Lessons in this course (12)

4. Error handling and logging best practices

Intermediate★ Must knowLesson 4 of 12
  • Throw exceptions for exceptional situations; use TryX or a Result type for expected failures (validation, not found).
  • Catch only what you can handle; let the rest bubble to a global exception handler (ASP.NET Core UseExceptionHandler + IExceptionHandler / ProblemDetails).
  • Never swallow exceptions (catch { }).
  • Structured logging with message templates, not string interpolation:
csharp
// ❌ logger.LogInformation($"Order {orderId} placed by {userId}");   // allocates always; loses structure
// ✅
logger.LogInformation("Order {OrderId} placed by {UserId}", orderId, userId);

// High-performance, source-generated:
public static partial class Log
{
    [LoggerMessage(Level = LogLevel.Warning, Message = "Payment {PaymentId} failed: {Reason}")]
    public static partial void PaymentFailed(ILogger logger, string paymentId, string reason);
}
  • Never log secrets, passwords, tokens or full card numbers; mask PII.
  • Use correlation IDs / OpenTelemetry trace IDs to follow a request across services.