造轮子之统一业务异常处理

2023-10-18 19:55:12 浏览数 (2)

异常处理也是我们必不可少的一环,借助Asp.netCore的UseExceptionHandler中间件,我们可以很轻易的配置我们的业务异常处理逻辑。

自定义业务异常类

首先我们定义一个业务异常类,继承Exception,添加一个Code状态码属性,和MessageData数组,这个数组用于Format异常信息。在实际业务场景中可以灵活扩展此类。

代码语言:javascript复制
namespace Wheel.Core.Exceptions
{
    public class BusinessException : Exception
    {
        public string Code { get; set; }

        public string[]? MessageData { get; set; }

        public BusinessException(string code, string? message = "") : base(message)
        {
            Code = code;
        }

        public BusinessException WithMessageDataData(params string[] messageData)
        {
            MessageData = messageData;
            return this;
        }
    }
}

约定错误码

在业务开发中,我们经常需要根据错误码去判断具体的业务错误类型。所以我们需要约定一个错误码格式。 创建一个ErrorCode类。

代码语言:javascript复制
/// <summary>
/// 错误码
/// 约定5位数字字符串
/// 4XXXX:客户端错误信息
/// 5XXXX: 服务端错误信息
/// </summary>
public class ErrorCode
{
    #region 5XXXX
    public const string InternalError = "50000";
    #endregion
    #region 4XXXX
    #endregion
}

这里我们约定一下5位数错误码,5开头则服务端的错误类型,4开头则客户端错误类型。当然,往后可以按照实际业务需求做出更多的约定或者改动。

UseExceptionHandler

接下来使用UseExceptionHandler配置我们的异常处理逻辑。 在Program中添加代码。

代码语言:javascript复制
app.UseExceptionHandler(exceptionHandlerApp =>
{
    exceptionHandlerApp.Run(async context =>
    {
        context.Response.StatusCode = StatusCodes.Status500InternalServerError;

        // using static System.Net.Mime.MediaTypeNames;
        context.Response.ContentType = Application.Json;
        var exceptionHandlerPathFeature =
            context.Features.Get<IExceptionHandlerPathFeature>();

        if (exceptionHandlerPathFeature?.Error is BusinessException businessException)
        {
            var L = context.RequestServices.GetRequiredService<IStringLocalizerFactory>().Create(null);
            if (businessException.MessageData != null)
                await context.Response.WriteAsJsonAsync(new R { Code = businessException.Code, Message = L[businessException.Message, businessException.MessageData] });
            else
                await context.Response.WriteAsJsonAsync(new R { Code = businessException.Code, Message = L[businessException.Message] });
        }
        else
        {
            await context.Response.WriteAsJsonAsync(new R { Code = ErrorCode.InternalError, Message = exceptionHandlerPathFeature?.Error.Message });
        }
    });
});

这里判断如果是我们的BusinessException类型异常,则返回统一的Json结构,并且使用多语言处理我们的异常信息。

到这我们就轻松的完成了我们的统一业务异常处理。

0 人点赞