全局异常拦截,业务异常直接被转成RuntimeException,为啥异常不让抛出

为啥拦截器这里要强制吧异常转换成RuntimeException,我在业务中建了一个自己的业务异常类

public class BaseException extends Exception implements Serializable {

    private static final long serialVersionUID = 2007525058641283836L;

    private String code;

    public BaseException(String code, String msg) {
        super(msg);
        this.code = code;

    }

    public BaseException(BaseError baseError) {
        super(baseError.getMsg());
        this.code = baseError.getCode();
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

}

然后建了一个异常拦截器

public class ExceptionInterceptor implements Interceptor {

    @Override
    public void intercept(Invocation me) {

        try {
            me.invoke();
        }catch (Exception e){

            HttpServletResponse response = me.getController().getResponse();
            response.setStatus(200);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            PrintWriter writer = null;
            try {
                writer = response.getWriter();
            } catch (IOException e1) {
                e1.printStackTrace();
                me.getController().renderError(500);
            }
            BaseResponse resp = new BaseResponse();
            if (e instanceof BaseException) {

                resp.setCode(((BaseException) e).getCode());
                resp.setMessage(e.getMessage());
            }else {
                resp.setCode(BaseError.SYSTEM_ERR.getCode());
                resp.setMessage(BaseError.SYSTEM_ERR.getMsg());
            }
            writer.write(JSON.toJSONString(resp));
            writer.flush();
            writer.close();
        }

    }
}

单步调试,故意让业务抛出一个BaseException业务异常,结果走到下图invoke中最先被捕捉

} catch (InvocationTargetException var3) {

,导致异常类型被改变成RuntimeException,接着往下走到自己的拦截器ExceptionInterceptor时,导致不能根据业务异常类型判断了

public class Invocation {
    public void invoke() {
        if (this.index < this.inters.length) {
            this.inters[this.index++].intercept(this);
        } else if (this.index++ == this.inters.length) {
            try {
                if (this.action != null) {
                    this.returnValue = this.action.getMethod().invoke(this.target, this.args);
                } else if (this.useInjectTarget) {
                    this.returnValue = this.methodProxy.invoke(this.target, this.args);
                } else {
                    this.returnValue = this.methodProxy.invokeSuper(this.target, this.args);
                }
            } catch (InvocationTargetException var3) {
                Throwable t = var3.getTargetException();
                throw t instanceof RuntimeException ? (RuntimeException)t : new RuntimeException(var3);
            } catch (RuntimeException var4) {
                throw var4;
            } catch (Throwable var5) {
                throw new RuntimeException(var5);
            }
        }
    
    }
}

各位怎么处理全局异常拦截的?

评论区

JFinal

2018-07-28 21:35

用一个全局拦截器,大致代码如下:
try {
inv.invoke();
}
catch (Exception e) {
Throwable t = e.getTargetException();
if (t instanceof 你的业务异常类理) {
// 处理业务异常:
// 例如: inv.getController().renderJson(...);
}
else if (t instanceof 其它异常类型) {
....
}

wesleyxw

2018-07-29 09:33

wesleyxw

2018-07-29 12:53

@JFinal 刚试了下,e.getTargetException();方法找不到,用e.getCause();代替可以用

HingLo

2018-07-30 08:57

全局异常拦截器,你可以配置多个catch,但是Exception放在最后一个catch中,例如: try {
inv.invoke();
} catch (ActiveRecordException e) {

e.printStackTrace();
inv.getController().renderJson(ResultUtils.error("数据库操作失败,请联系管理员"));
} catch (cn.hutool.core.date.DateException e) {
e.printStackTrace();
inv.getController().renderJson(ResultUtils.error("指定日期格式不正确"));
} catch (Exception e) {
e.printStackTrace();
inv.getController().renderJson(ResultUtils.error("其他异常信息"));
}

wesleyxw

2018-07-30 14:24

@HingLo 好的,谢谢

热门反馈

扫码入社