Exception handling middleware doesn't handle exceptions - Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware is called (ASP.NET Core WebAPI)

Viewed 1641

I created an exception handling middleware according to this example:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseExceptionHandler("/error");
    
    // ...
}

[AllowAnonymous]
[ApiExplorerSettings(IgnoreApi = true)]
[ApiController]
public class ErrorsController : ControllerBase
{
    [Route("error")]
    public IActionResult Error()
    {
        return Problem();
    }
}

Now let's say that I threw the following exception: throw new Exception("BAX");
My exception handling middleware catches this exception and works great. But the problem is that in console I see the following log:

|ERROR|Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware|An unhandled exception has occurred while executing the request.|System.Exception: BAX (stack trace goes here)

Note: I removed stack trace to make it a little bit shorter.

Maybe I should also say that I use NLog for logging. Here is the configuration of it:

<target xsi:
    type = "ColoredConsole" name = "colored_console"
    layout = "|${level:uppercase=true}|${logger}|${message}|${exception:format=tostring}">
</target >

Question

My exception was caught by Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware. It looks like my exception handling middleware didn't handle the exception. Am I right?

My question is why it works so and how can I fix it?

1 Answers

The duty of app.UseExceptionHandler("errors") is log errors then redirect users to a page in order to show them a proper message.

First of all, when you have app.UseExceptionHandler("errors") it means, ASP.NET Core redirects to a controller named errors and according to your code, it won't work because your Conroller name is Errors and in your code you defined error as its path.

if you don't want Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware to be called, then you have to write your own middleware and log errors there. here is an example of custom middleware to catch all exceptions.

   public class CustomMiddlewareMiddleware
{
    private readonly RequestDelegate _next;

    public CustomMiddlewareMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext httpContext)
    {
        try
        {
            await _next(httpContext);
           
        }
        catch (System.Exception)
        {

            /// log it here and then redirect to spesific path
       
            if (httpContext.Response.StatusCode == 404 && !httpContext.Response.HasStarted)
            {
                httpContext.Request.Path = "/error/404/";
                await _next(httpContext);
            }
        }
      
    }
}
Related