这两天工作时间有点空闲,总结上个项目的不足,重新捋了一下学习点。
我负责后端的开发,基础比较弱,公司内部也没有形成一套很好的规范,一切都是摸着石头过河。在与前端的API对接中,存在着这样那样的问题,最烦人的一点的出错了怎么返回,返回的结果有这样式的也有那样式的,弄得不是很开心。
在编写接口的过程中,我只有一部分是用try ... catch
来捕捉异常,然后其他就任由系统报错,这肯定是不行的,正好前两天浏览技术文章的时候,虽然是spring的,但为我打开了大门,那就是全局统一异常处理。
其实说起来也是很简单的,按理说我应该要知道的,只是基础太差,没写过类似的,那就是异常过滤器或者异常中间件。
异常过滤器
public class GlobalExceptionFilter: IExceptionFilter
{
private readonly IHostEnvironment _env;
public GlobalExceptionFilter(IHostEnvironment env)
{
_env = env;
}
public void OnException(ExceptionContext context)
{
var result = new ContentResult
{
StatusCode = 500,
ContentType = "text/json;charset=utf-8",
Content = JsonConvert.SerializeObject(context.Exception.Message)
};
context.Result = result;
context.ExceptionHandled = true;
}
}
只要出现了catch
到的或者没catch
到的异常,那么api返回的时候肯定是能捕捉到的,而不是返回给前端一些不受控制的结果,当然,这个异常过滤器生效的前提是在调用方法之上加上此过滤器。
异常中间件
相比于异常过滤器只能在每一个方法中添加,如果我有很多api,每个api里面有很多方法,那我岂不是每个都要添加吗?那就用异常中间件一劳永逸吧。
public class MyExceptionMiddleware
{
private readonly RequestDelegate _next;
public MyExceptionMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch(Exception ex)
{
var content = ex.Message;
var problem = new ProblemDetails
{
Status = 200,
Title = content
};
var stream = httpContext.Response.Body;
await System.Text.Json.JsonSerializer.SerializeAsync(stream, problem);
}
}
}
与其他中间件写法类似,同样地,在StartUp.cs
文件中的Configure
方法内,添加中间件代码
app.UseMiddleware<MyExceptionMiddleware>();
至此,我便能大致地控制了所有异常的格式与返回的结构了。