.NET › Global Exception Handling & Middleware
How does the IExceptionHandler interface (introduced in .NET 8) provide a more structured alternative to the UseExceptionHandler lambda approach?
IntermediateAnswer
IExceptionHandler defines a TryHandleAsync(HttpContext, Exception, CancellationToken) method that you implement as a proper, testable, DI-injectable class rather than an inline delegate -- multiple exception handlers can be registered and are tried in order until one returns true (indicating it handled the exception), enabling different handlers for different exception types (like a specific handler for validation exceptions and a fallback handler for everything else) in a clean, composable way.
public class ValidationExceptionHandler : IExceptionHandler {
public async ValueTask<bool> TryHandleAsync(HttpContext context, Exception exception, CancellationToken ct) {
if (exception is not ValidationException ve) return false; // not handled, try next handler
context.Response.StatusCode = 400;
await context.Response.WriteAsJsonAsync(new { errors = ve.Errors }, ct);
return true;
}
}
builder.Services.AddExceptionHandler<ValidationExceptionHandler>();
builder.Services.AddExceptionHandler<GlobalExceptionHandler>(); // fallbackReal-world example An API registers a specific ValidationExceptionHandler that formats validation errors distinctly, chained with a catch-all GlobalExceptionHandler for everything else, replacing what used to be a large if/else chain inside a single exception-handling lambda.