Solon v2.9.2

统一的异常处理 - new

</> markdown

此内容适合 v2.8.3 之后


关于全局的请求异常处理,最好就是用过滤器(或者用路由拦截器)。。。因为它是最外层的,还可以捕捉 mvc 之外的异常。。。也适合做:跟踪标识添加、流量控制、处理计时、请求日志(ctx.result 可以获取处理结果)、异常日志等等。

此文多了StatusException,只适合 v2.8.1 之后。以下为简单异常控制示例(只是示例,具体根据自己的情况处理):

1、示例1:控制异常,并以状态码输出

  • Filter 实现版
@Component(index = 0) //index 为顺序位(不加,则默认为0)
public class AppFilter implements Filter {
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        try {
            chain.doFilter(ctx);
        } catch (StatusException e){
            ctx.status(e.getCode()); //可能的状态码为:4xxx
        } catch (Throwable e) {
            ctx.status(500);
        }
    }
} 
  • RouterInterceptor 实现版(差不多,范围只限动态请求)
@Component(index = 0) //index 为顺序位(不加,则默认为0)
public class AppRouterInterceptor implements RouterInterceptor {
    @Override
    public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
        try {
            chain.doIntercept(ctx, mainHandler);
        } catch (StatusException e){
            ctx.status(e.getCode()); //可能的状态码为:4xxx
        } catch (Throwable e) {
            ctx.status(500);
        }
    }
} 

2、示例2:控制异常,并以Json格式渲染输出

  • Filter 实现版
@Component(index = 0) //index 为顺序位(不加,则默认为0)
public class AppFilter implements Filter {
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        try {
            chain.doFilter(ctx);
        } catch (AuthException e){
            ctx.render(Result.failure(e.getCode, "你没有权限"));
        } catch (ValidatorException e){
            ctx.render(Result.failure(e.getCode(), e.getMessage())); //e.getResult().getDescription()
        } catch (StatusException e){
            if (e.getCode() == 404){
                ctx.status(e.getCode()); 
            } else {
                ctx.render(Result.failure(e.getCode, e.getMessage()));
            }
        } catch (Throwable e) {
            ctx.render(Result.failure(500, "服务端运行出错"));
        }
    }
} 
  • RouterInterceptor 实现版(差不多,范围只限动态请求)
@Component(index = 0) //index 为顺序位(不加,则默认为0)
public class AppRouterInterceptor implements RouterInterceptor {
    @Override
    public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
        try {
            chain.doIntercept(ctx, mainHandler);
        } catch (AuthException e){
            ctx.render(Result.failure(e.getCode, "你没有权限"));
        } catch (ValidatorException e){
            ctx.render(Result.failure(e.getCode(), e.getMessage())); //e.getResult().getDescription()
        } catch (StatusException e){
            if (e.getCode() == 404){
                ctx.status(e.getCode()); 
            } else {
                ctx.render(Result.failure(e.getCode, e.getMessage()));
            }
        } catch (Throwable e) {
            ctx.render(Result.failure(500, "服务端运行出错"));
        }
    }
}