【问题标题】:Exception handling middleware doesn't handle exceptions - Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware is called (ASP.NET Core WebAPI)异常处理中间件不处理异常 - 调用 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware (ASP.NET Core WebAPI)
【发布时间】:2021-08-06 14:35:14
【问题描述】:

我根据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");
我的异常处理中间件捕获了这个异常并且效果很好。但问题是在控制台中我看到以下日志:

|错误|Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware|执行请求时发生未处理的异常。|System.Exception: BAX(此处为堆栈跟踪)

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

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

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

问题

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

我的问题是它为什么会这样,我该如何解决?

【问题讨论】:

    标签: c# api asp.net-core asp.net-web-api middleware


    【解决方案1】:

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

    首先,当你有 app.UseExceptionHandler("errors") 时,这意味着 ASP.NET Core 重定向到一个名为 errors 的控制器,根据你的代码,它不会工作,因为你的 @987654325 @ 名称是 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);
                }
            }
          
        }
    }
    

    【讨论】:

    • 感谢您的回答!在我的项目中,我没有app.UseExceptionHandler("errors") - 我有app.UseExceptionHandler("error"),因此它工作得很好。但是为什么要创建中间件而不是异常过滤器呢?
    • 在你的问题中,你有这个`app.UseExceptionHandler("/error");`并且你的控制器名称是errors,这些不一样
    • ErrorsController 没有任何路线。 Route/error 是到这个控制器的 action 方法的路由。如您所见,此控制器内部有一个名为Error 的操作方法。这个动作方法上面有如下属性:[Route("error")]
    • 但是我又想知道,为什么在这种情况下我应该使用中间件而不是异常过滤器?
    • 在您的评论中您说,我们如何避免调用Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware,我想您可能想要拥有自己的中间件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 2020-12-16
    • 2014-06-18
    • 2015-12-21
    • 1970-01-01
    • 2022-07-01
    相关资源
    最近更新 更多