Intro
ASP.NET 8 中引入了 IExceptionHandler,我们可以针对某一类的 exception 做单独的处理,
可以将不同类型的异常有不一样的逻辑做不同的处理,异常处理可以变得更加灵活
Sample
来看一个简单的示例:
我们可以实现 IExceptionHandler 来处理异常:
file sealed class ArgumentExceptionHandler : IExceptionHandler
{
public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{
httpContext.RequestServices.GetRequiredService<ILogger<ArgumentExceptionHandler>>()
.LogError(exception, "Exception handled");
if (exception is not ArgumentException) return false;
httpContext.Response.StatusCode = 400;
await httpContext.Response.WriteAsJsonAsync(new
{
exception.Message
}, cancellationToken);
return true;
}
}
只需要实现 TryHandleAsync 方法即可,返回值是 true 代表已经已经处理 ,无需后面的 exception handle 逻辑再处理,false 则需要后面的逻辑进行处理
完整的 web app 示例如下:
通过 AddExceptionHandler
另外需要通过 UseExceptionHandler() 注册 ExceptionHandler 中间件
需要指定一下 exception handler 未处理的情况下的 exception 路由 ExceptionHandlingPath 或者 exception 处理逻辑 ExceptionHandler
var builder = WebApplication.CreateSlimBuilder(args);
builder.Services.AddExceptionHandler<ArgumentExceptionHandler>();
var app = builder.Build();
app.UseExceptionHandler(new ExceptionHandlerOptions()
{
// ExceptionHandlingPath = "/",
ExceptionHandler = context =>
{
context.Response.StatusCode = 500;
context.Response.WriteAsJsonAsync(new
{
title = "Internal Error",
traceId = context.TraceIdentifier
});
return Task.CompletedTask;
}
});
app.MapGet("/", () => "Hello .NET 8!");
app.MapGet("/exception", () =>
{
throw new InvalidOperationException("Oh no...");
});
app.MapGet("/argument-exception", () =>
{
throw new ArgumentException("Oh no...");
});
await app.RunAsync();
我们在示例中添加了三种效果,没有异常、InvalidOperationException/ArgumentException
这样我们可以把 exception 分层处理,不同的处理逻辑放在不同的 exception handler 中,不需要定义在一个地方,这样就灵活了许多,相当于中间件里套了一层中间件,套娃,嘿嘿
标签:exception,ASP,处理,app,中间件,ExceptionHandler,new,NET From: https://www.cnblogs.com/fanfan-90/p/17972366