0

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!

4
  • An exception can only be caught once unless the code that catches the exception uses a THROW. Most libraries do no have THROWS so you cannot catch the exception a second time. Commented Aug 29, 2024 at 6:55
  • Show the code throwing "natural exception" and make sure it is not caught somewhere already. Commented Aug 29, 2024 at 6:58
  • So if an exception occurs and it is not being caught anywhere, and not rethrown, basically the exception wasn't expected and is not being handled anywhere in the code, would it come to the exception handler? Commented Aug 29, 2024 at 8:23
  • 1
    You could try built in exception handling middleware which will help you catch all the Unhandled exceptions. for your first question: The IExceptionHandler only works when middleware is confiure to use it. If your application doesn't have this middleware set up correctly, or if the exception doesn't reach the middleware due to being handled earlier in the pipeline, your TryHandleAsync method won't be invoked. Commented Aug 29, 2024 at 10:00

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.