异常处理中间件不处理异常 - Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware 被调用(ASP.NET Core WebAPI)

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

我根据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();
    }
}

现在假设我抛出了以下异常:throw new Exception("BAX");
我的异常处理中间件捕获了这个异常并且运行良好。但问题是在控制台中我看到以下日志:

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

注意:我删除了堆栈跟踪以使其更短一些。

也许我还应该说我使用 NLog 进行日志记录。这是它的配置:

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

问题

我的异常被 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware 捕捉到了。 看起来我的异常处理中间件没有处理异常。我说得对吗?

我的问题是为什么它如此有效,我该如何解决它?

app.UseExceptionHandler("errors") 的职责是 log 错误然后将用户重定向到一个页面以向他们显示正确的消息。

首先,当你有app.UseExceptionHandler("errors")时,这意味着,ASP.NET核心重定向到一个名为errors的控制器,并根据你的代码,它不会工作,因为你的 Conroller 名称是 Errors 并且在你的代码中你将 error 定义为它的路径。

如果您不想调用 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware,那么您必须编写自己的中间件并在其中记录错误。这是捕获所有异常的自定义中间件示例。

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