在 ASP.NET Core 8 中配置自定义异常处理程序

作者:微信公众号:【架构师老卢】
6-8 9:25
97

概述:若要增强 ASP.NET Core 应用程序的复原能力和用户体验,实现自定义异常处理至关重要。本文将指导你配置自定义的“IExceptionHandler”实现,从而实现更结构化、信息更丰富的错误处理方法。先决条件若要将“IExceptionHandler”实现添加到 ASP.NET Core 请求管道,需要:1. 使用依赖注入注册“IExceptionHandler”服务。2. 在请求管道中注册“ExceptionHandlingMiddleware”。第 1 步:注册服务首先,需要将自定义异常处理程序注册为具有单例生存期的服务。请注意注入具有不同生存期的服务,以避免潜在问题。在这里,我们还

若要增强 ASP.NET Core 应用程序的复原能力和用户体验,实现自定义异常处理至关重要。本文将指导你配置自定义的“IExceptionHandler”实现,从而实现更结构化、信息更丰富的错误处理方法。

先决条件

若要将“IExceptionHandler”实现添加到 ASP.NET Core 请求管道,需要:

1. 使用依赖注入注册“IExceptionHandler”服务。
2. 在请求管道中注册“ExceptionHandlingMiddleware”。

第 1 步:注册服务

首先,需要将自定义异常处理程序注册为具有单例生存期的服务。请注意注入具有不同生存期的服务,以避免潜在问题。

在这里,我们还使用“AddProblemDetails”为常见异常生成详细响应。

builder.Services.AddExceptionHandler<CustomGlobalExceptionHandler>();  
builder.Services.AddProblemDetails();

第 2 步:添加中间件

接下来,通过调用“UseExceptionHandler”将“ExceptionHandlingMiddleware”添加到请求管道:

app.UseExceptionHandler();
internal sealed class CustomGlobalExceptionHandler : IExceptionHandler
{
    private readonly ILogger<CustomGlobalExceptionHandler> _logger;

    public CustomGlobalExceptionHandler(ILogger<CustomGlobalExceptionHandler> logger)
    {
        _logger = logger;
    }

    public async ValueTask<bool> TryHandleAsync(
        HttpContext httpContext,
        Exception exception,
        CancellationToken cancellationToken)
    {
        _logger.LogError(
            exception,
            "Unhandled exception occurred: {Message}",
            exception.Message);

        var problemDetails = new ProblemDetails
        {
            Status = StatusCodes.Status500InternalServerError,
            Title = "Internal Server Error",
            Detail = "An unexpected error occurred. Please try again later."
        };

        httpContext.Response.StatusCode = problemDetails.Status.Value;

        await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken);

        return true;
    }
}

实现多个异常处理程序

ASP.NET Core 允许您添加多个“IExceptionHandler”实现,这些实现按注册顺序顺序调用。这对于使用异常进行流控制等方案特别有用。

定义自定义例外

定义自定义异常,例如“BadRequestException”和“NotFoundException”,这些异常与 API 返回的 HTTP 状态代码相对应。

internal sealed class BadRequestExceptionHandler : IExceptionHandler
{
    private readonly ILogger<BadRequestExceptionHandler> _logger;

    public BadRequestExceptionHandler(ILogger<BadRequestExceptionHandler> logger)
    {
        _logger = logger;
    }

    public async ValueTask<bool> TryHandleAsync(
        HttpContext httpContext,
        Exception exception,
        CancellationToken cancellationToken)
    {
        if (exception is not BadRequestException badRequestException)
        {
            return false;
        }

        _logger.LogError(
            badRequestException,
            "Exception occurred: {Message}",
            badRequestException.Message);

        var problemDetails = new ProblemDetails
        {
            Status = StatusCodes.Status400BadRequest,
            Title = "Bad Request",
            Detail = badRequestException.Message
        };

        httpContext.Response.StatusCode = problemDetails.Status.Value;

        await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken);

        return true;
    }
}
internal sealed class NotFoundExceptionHandler : IExceptionHandler
{
    private readonly ILogger<NotFoundExceptionHandler> _logger;

    public NotFoundExceptionHandler(ILogger<NotFoundExceptionHandler> logger)
    {
        _logger = logger;
    }

    public async ValueTask<bool> TryHandleAsync(
        HttpContext httpContext,
        Exception exception,
        CancellationToken cancellationToken)
    {
        if (exception is not NotFoundException notFoundException)
        {
            return false;
        }

        _logger.LogError(
            notFoundException,
            "Exception occurred: {Message}",
            notFoundException.Message);

        var problemDetails = new ProblemDetails
        {
            Status = StatusCodes.Status404NotFound,
            Title = "Not Found",
            Detail = notFoundException.Message
        };

        httpContext.Response.StatusCode = problemDetails.Status.Value;

        await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken);

        return true;
    }
}

注册处理程序

注册两个异常处理程序,以确保它们是请求管道的一部分:

builder.Services.AddExceptionHandler<BadRequestExceptionHandler>();  
builder.Services.AddExceptionHandler<NotFoundExceptionHandler>();  
builder.Services.AddExceptionHandler<CustomGlobalExceptionHandler>();  
builder.Services.AddProblemDetails();

在此设置中,“BadRequestExceptionHandler”将首先尝试处理异常。如果它无法处理异常,则接下来将调用“NotFoundExceptionHandler”。

通过执行这些步骤,可以在 ASP.NET Core 应用程序中配置自定义异常处理程序。此方法提供了一种可靠的机制,用于管理不同类型的异常并改进应用程序中的整体错误处理策略。实施详细的问题响应不仅可以增强用户体验,还有助于调试和维护。

阅读排行