Interceptor中catch到的异常包装后再次抛出, 在外层的Interceptor中catch不到这个异常

比如我这个操作日志的拦截器,我只负责记录操作日志. 异常处理我想让更外层的拦截器去处理. 但是我发现从这里catch 并 throw出去的异常就好像是消失了一样, 更外层的Interceptor根本catch不到, @Jfinal 请教一下是什么原因

jfinal 版本 3.5 

jdk 1.8 u21

public class OperationLogInterceptor implements Interceptor {
    // 操作日志记录报错
    private final static Log log = Log.getLog(OperationLogInterceptor.class);

    private static final String METHOD_TYPE = Constants.METHOD_POST;
    private static final String CONTENT_TYPE = Constants.CONTENT_TYPE;

    private static final String ERROR_TYPE = "ERROR";
    private static final String INFO_TYPE = "INFO";

    private Controller controller;
    private Throwable ex;
    private OperationLog operationLogAnno;
    private Object args;

    private long startTimeStamp;
    private long endTimeStamp;

    @Override
    public void intercept(Invocation inv) {
        if(!inv.isActionInvocation())
            throw new RuntimeException("OperationLogInterceptor只能用于action方法记录操作日志");

        try {
            // 这里要重置ex异常记录
            this.ex = null;
            this.startTimeStamp = System.currentTimeMillis();
            inv.invoke();
        } catch(RuntimeException e) {
            this.ex = e;
            throw e;
        } catch (Throwable e) {
            this.ex = e;
            throw new RuntimeException(e);
        } finally {
            this.endTimeStamp = System.currentTimeMillis();
            Method method = inv.getMethod();
            boolean hasAnno = method.isAnnotationPresent(OperationLog.class);
            if(!hasAnno) {
                return;
            }
            args = inv.getArgs() != null && inv.getArgs().length > 0 ? inv.getArg(0) : null;
            controller = inv.getController();
            operationLogAnno = method.getAnnotation(OperationLog.class);
            try {
                // 记录操作日志
                log();
            } catch (Exception ex) {
                log.error("记录操作日志异常: " + ExceptionUtils.getStackTrace(ex), ex);
            }
        }
    }

    /**
     * 记录操作日志
     */
    private void log() {
        HttpServletRequest request = controller.getRequest();
        // HttpServletResponse response = controller.getResponse();
        Render render = controller.getRender();

        String ip = IpKit.getIpAddr(request);
        String method = request.getMethod();
        String url = request.getRequestURL().toString();
        String queryStr = request.getQueryString();
        String uri = StrKit.notBlank(queryStr) ? url + "?" + queryStr : url;
        String contentType = request.getContentType();

        String resStr = "";
        if(render instanceof JsonRender) {
            resStr += ((JsonRender) render).getJsonText();
        } else if(render instanceof TextRender) {
            resStr += ((TextRender)render).getText();
        }

        long executeTime = endTimeStamp - startTimeStamp;

        OperationLogModel operationLogModel = new OperationLogModel()
                .setExecuteTime(executeTime)
                .setIp(ip)
                .setUserId(StringUtils.defaultString(UserUtils.getCurrentUserId()))
                .setUserName(StringUtils.defaultString(UserUtils.getCurrentUsername()))
                .setMethod(method)
                .setRequestUri(uri)
                .setLogType(ex != null ? ERROR_TYPE : INFO_TYPE)
                .setModule(operationLogAnno.module())
                .setAction(operationLogAnno.action())
                .setParams(METHOD_TYPE.equalsIgnoreCase(method)
                        && StrKit.notBlank(contentType)
                        && contentType.contains(CONTENT_TYPE)
                        && args != null
                        ? JsonKit.toJson(args)
                        : JsonKit.toJson(new HashMap<>(controller.getParaMap())))
                .setResponse(ex != null ? ExceptionUtils.getStackTrace(ex) : resStr);
        // 异步记录
        EventKit.post(new OperationLogEvent(operationLogModel));
    }

}


评论区

JFinal

2018-12-19 15:13

有可能是finally 块中吃掉了异常,单步调试一下,这个不是 jfinal 的范畴,纯 java 语言的范畴

woshify

2018-12-19 20:10

@JFinal 感谢回复, 我上午已经找到问题了. 我finally块中的return语句覆盖了我的异常栈, 我不使用
if(!hasAnno) {
return;
}
就没问题了

热门反馈

扫码入社