【X23】 02 全局错误捕捉(Middleware)

前言

知识点:
ASP.NET Core 中基于工厂的中间件激活
目的: 利用 Middleware 自定义中间件捕捉程序全局错误

1 简单介绍

中间件是一种装配到应用管道以处理请求和响应的软件。 每个组件:

  • 选择是否将请求传递到管道中的下一个组件。
  • 可在管道中的下一个组件前后执行工作。

request-delegate-pipeline
request-delegate-pipeline
首先看看最重要的两张图,详细描述了中间件执行过程以及顺序。通俗来说,就是委托包委托,请求进来先按规定顺序执行多个中间件的方法,再依次倒着返回结果。
所以,我们可以通过自定义错误处理中间件,捕捉程序运行的错误!

2 编写错误中间件

中间件的编写方式有三种

在此,我采用了第二种基于工厂的中间件激活,因为第一种约定方式对编写理解不友好,第三种过于复杂。
简单来说,我们可以通过一个方法 RequestDelegate next 进行 try catch 住,然后扩展对错误的处理。

/// <summary>
/// 错误处理中间件
/// </summary>
public class ErrorHandlingMiddleware: IMiddleware
{
    private readonly ILoggerFactory _loggerFactory;

    public ErrorHandlingMiddleware(ILoggerFactory loggerFactory)
    {
        _loggerFactory = loggerFactory;
    }

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex, _loggerFactory);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception exception, ILoggerFactory loggerFactory)
    {
        var logger = loggerFactory.CreateLogger("HandleException");
        logger.LogError(exception, exception.Message);

        var code = HttpStatusCode.InternalServerError;
        context.Response.StatusCode = (int)code;
        return context.Response.WriteAsJsonAsync(new ResponseDto { Code = (int)code, ErrorMsg = exception.Message, StackTrace = exception.StackTrace });
    }
}

3 注册使用该中间件

一般来说,中间件的注册使用如下,但是为什么别人都是 service.AddXXX()app.UseXXX() 如此优雅呢?

services.AddTransient<ErrorHandlingMiddleware>();//注册
app.UseMiddleware<ErrorHandlingMiddleware>();//使用

改善后:

public static class AllMiddlewareExtensions
{
    /// <summary>
    /// 注册 异常处理中间件
    /// </summary>
    /// <param name="services"></param>
    public static void AddErrorHandlingMiddleware(this IServiceCollection services)
    {
        services.AddTransient<ErrorHandlingMiddleware>();
    }
    /// <summary>
    /// 使用 异常处理中间件
    /// </summary>
    /// <param name="builder"></param>
    /// <returns></returns>
    public static IApplicationBuilder UseErrorHandlingMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<ErrorHandlingMiddleware>();
    }
}

Now,你可以优雅的使用了!

services.AddErrorHandlingMiddleware();//注册
app.UseErrorHandlingMiddleware();//使用

4 大功告成!源码下载

posted @ 2022-05-22 17:29  Boring246  阅读(55)  评论(0)    收藏  举报