skip to Main Content

I’m working on an ASP.NET Core application and I’ve implemented a custom global exception handler using the `IExceptionHandler` interface. My goal is to catch and handle all unhandled exceptions that occur within the application and return a `ProblemDetails` response. Here’s the code for my `GlobalExceptionHandler` class:

public class GlobalExceptionHandler : IExceptionHandler {     

    private readonly ILogger _logger = Log.ForContext(typeof(GlobalExceptionHandler));      
    
    public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)     
    {         
        _logger.Error(exception, "Global Exception Handler");          
        var problemDetails = new ProblemDetails{             
            Status = (int)HttpStatusCode.InternalServerError,             
            Title = "An exception occurred",             
            Detail = exception.Message         };          

        httpContext.Response.StatusCode = problemDetails.Status.Value;         
        httpContext.Response.ContentType = "application/problem+json";          
        await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken);          
        return true;    
    } 
} 

However, I noticed that this handler only catches exceptions that are explicitly thrown (e.g., `throw new Exception("…")`) and not those that occur naturally within the application, such as null reference exceptions or other runtime errors. Questions:

1. Why isn’t my `IExceptionHandler` implementation catching all exceptions within the application?
3. If `IExceptionHandler` is not suitable for this purpose, what is the recommended way to handle all unhandled exceptions globally without writing custom middleware (the reason we are using Microsoft.AspNetCore.Diagnostics.IExceptionHandler is that it doesn’t require us to write a middleware)?

Any guidance or best practices would be greatly appreciated!

2

Answers


  1. Chosen as BEST ANSWER

    Thank you for your answers everyone. Since this was a while ago, I don't remember exactly but I am pretty sure the exception being thrown from one of the middleware was being handled in another middleware implicitly. I removed all the try catch blocks from subsequent pieces of middleware or rethrew the exception until it was unhandled and it worked. So basically the comments pointed me in the right direction, I just couldn't get to the root of it.


    1. I read somewhere that since this global handler is async, your routes must be async as well. You might want to check that.

    2. Review how you’re injecting this global handler in your Program.cs. Here’s the approach I use, which works fine:

    builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
    
    app.UseExceptionHandler(o => { }); // I'm passing an empty delegate because, for some reason, it doesn't work properly if it's empty, maybe it's a bug, idk...
    

    Asides from that, my GlobalExceptionHandler is very similar to yours…

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search