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

Posted

技术标签:

【中文标题】异常处理中间件不处理异常 - 调用 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) 【发布时间】: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 捕获。 看起来我的异常处理中间件没有处理异常。我说的对吗?

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

【问题讨论】:

【参考方案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,我想您可能想要拥有自己的中间件。

以上是关于异常处理中间件不处理异常 - 调用 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware (ASP.NET Core WebAPI)的主要内容,如果未能解决你的问题,请参考以下文章

asp.net core 自定义异常处理中间件

java 异常不处理会怎么样

异常处理中间件和页面

Python --- 异常处理

Error Handling in ASP.NET Core

Django 统一异常处理