异常处理¶
KnownException¶
我们在包NetCorePal.Extensions.Primitives
中定义了一个异常类KnownException
,用于表示已知异常,使得系统可以更友好的方式响应异常。
KnownException
实现了接口 IKnownException
,可以携带Message
、ErrorCode
、ErrorData
等更多的信息,接口定义如下:
public interface IKnownException
{
string Message { get; }
int ErrorCode { get; }
IEnumerable<object> ErrorData { get; }
}
异常处理中间件 KnownExceptionHandleMiddleware¶
我们在包NetCorePal.Extensions.AspNetCore
中定义了一个异常处理中间件KnownExceptionHandleMiddleware
,用于处理异常。
KnownExceptionHandleMiddleware
会捕获已知异常,并将异常信息转换为ResponseData
对象,然后返回给客户端,从而保持正常响应与异常响应具有相同的数据结构,方便前端处理。
如果异常不是已知异常,则会返回一个默认的错误信息,以屏蔽敏感信息,避免暴露系统内部异常。
使用方法如下,在Program.cs
文件中:
var builder = WebApplication.CreateBuilder(args);
//Add Other Services
var app = builder.Build();
app.UseKnownExceptionHandler();
KnownExceptionHandleMiddlewareOptions¶
KnownExceptionHandleMiddleware
的配置选项如下:
KnownExceptionStatusCode
: 已知异常响应状态码,默认为HttpStatusCode.OK
,即200
;UnknownExceptionStatusCode
: 非已知异常响应状态码,默认为HttpStatusCode.InternalServerError
,即500
;UnknownExceptionMessage
: 非已知异常响应消息,默认为"未知错误"
;UnknownExceptionCode
: 非已知异常响应错误码,默认为99999
;
具体代码定义如下:
public class KnownExceptionHandleMiddlewareOptions
{
public HttpStatusCode KnownExceptionStatusCode { get; set; } = HttpStatusCode.OK;
public HttpStatusCode UnknownExceptionStatusCode { get; set; } = HttpStatusCode.InternalServerError;
public string UnknownExceptionMessage { get; set; } = "未知错误";
public int UnknownExceptionCode { get; set; } = 99999;
}
动态异常处理配置¶
KnownExceptionHandleMiddleware
支持动态配置,通过注册一个工厂方法来实现:
Func<HttpContext, KnownExceptionHandleMiddlewareOptions>
下面是一个示例,当请求路径以/api/internal
开头时,使用option1
,否则使用option2
:
var app = builder.Build();
var option1 = new KnownExceptionHandleMiddlewareOptions {
KnownExceptionStatusCode = HttpStatusCode.InternalServerError,
UnknownExceptionStatusCode = HttpStatusCode.InternalServerError,
UnknownExceptionMessage = "未知错误",
UnknownExceptionCode = 99999
};
var option2 = new KnownExceptionHandleMiddlewareOptions {
KnownExceptionStatusCode = HttpStatusCode.OK,
UnknownExceptionStatusCode = HttpStatusCode.BadRequest,
UnknownExceptionMessage = "未知错误",
UnknownExceptionCode = 10000
};
app.UseKnownExceptionHandler(httpContext => {
if(httpContext.Request.Path.StartsWithSegments("/api/internal")) {
return option1;
}
else {
return option2;
}
});