Back to results for “.NET CLI”
.NET › Global Exception Handling & Middleware

How does the IExceptionHandler interface (introduced in .NET 8) provide a more structured alternative to the UseExceptionHandler lambda approach?

Intermediate

Answer

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>();  // fallback
Real-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.

Common follow-ups: What determines the order multiple registered IExceptionHandlers are tried in?;How does this integrate with ProblemDetails for standardized error responses?