简体   繁体   中英

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

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?

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);
            }
        }
      
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM