Solon v2.7.6

统一的异常处理

</> markdown

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

以下只是简单异常控制示例(只是示例,具体根据自己的情况处理):

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 (AuthException e){
            ctx.status(e.getStatus().code);
        } catch (ValidatorException e){
            ctx.status(e.getCode());
        } 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 (AuthException e){
            ctx.status(e.getStatus().code);
        } catch (ValidatorException e){
            ctx.status(e.getCode());
        } 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);

            if(ctx.getHandled() == false){
                ctx.render(Result.failure(404, "资源不存在"));
            }
        } catch (AuthException e){
            ctx.render(Result.failure(e.getStatus().code, "你没有权限"));
        } catch (ValidatorException e){
            ctx.render(Result.failure(e.getCode(), e.getMessage())); //e.getResult().getDescription()
        } 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);

            if(mainHandler == null){
                ctx.render(Result.failure(404, "资源不存在"));
            }
        } catch (AuthException e){
            ctx.render(Result.failure(e.getStatus().code, "你没有权限"));
        } catch (ValidatorException e){
            ctx.render(Result.failure(e.getCode(), e.getMessage())); //e.getResult().getDescription()
        } catch (Throwable e) {
            ctx.render(Result.failure(500, "服务端运行出错"));
        }
    }
}