.NET › Global Exception Handling & Middleware

How would you implement custom middleware to catch and log unhandled exceptions before they reach the exception handler, adding request-specific context?

Advanced

Answer

A custom try/catch-wrapping middleware placed early in the pipeline can capture and enrich exception context (like the request path, user identity, or a correlation ID) before re-throwing (or short-circuiting with a response) so downstream logging or the exception handler has richer diagnostic information -- though care must be taken not to swallow exceptions unintentionally or duplicate work already handled by UseExceptionHandler/IExceptionHandler.
public class ExceptionEnrichmentMiddleware {
    private readonly RequestDelegate _next;
    public async Task InvokeAsync(HttpContext context) {
        try {
            await _next(context);
        } catch (Exception ex) {
            ex.Data["RequestPath"] = context.Request.Path;
            ex.Data["UserId"] = context.User?.Identity?.Name;
            throw;  // re-throw for the actual exception handler to process
        }
    }
}
Real-world example A team adds enrichment middleware that tags every unhandled exception with the requesting user's ID and tenant context before it reaches the global exception handler, making production log entries dramatically more useful for tracing multi-tenant issues.

Common follow-ups: Why is it important to re-throw rather than swallow the exception in this pattern?;How does this compare to just adding this context directly inside a single IExceptionHandler?