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
TryXor 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.