protected Object visit()

in src/main/java/org/apache/commons/jexl3/internal/Interpreter.java [2172:2239]


    protected Object visit(final ASTTryStatement node, final Object data) {
        int nc = 0;
        final JexlNode tryBody = node.jjtGetChild(nc++);
        JexlException rethrow = null;
        JexlException flowControl = null;
        Object result = null;
        try {
            // evaluate the try
            result = tryBody.jjtAccept(this, data);
        } catch(JexlException.Return | JexlException.Cancel |
                JexlException.Break | JexlException.Continue xflow) {
            // flow control exceptions do not trigger the catch clause
            flowControl = xflow;
        } catch(final JexlException xany) {
            rethrow = xany;
        }
        JexlException thrownByCatch = null;
        if (rethrow != null && node.hasCatchClause()) {
            final ASTReference catchVar = (ASTReference) node.jjtGetChild(nc++);
            final JexlNode catchBody = node.jjtGetChild(nc++);
            // if we caught an exception and have a catch body, evaluate it
            try {
                // evaluate the catch
                result = evalCatch(catchVar, catchBody, rethrow, data);
                // if catch body evaluates, do not rethrow
                rethrow = null;
            } catch (JexlException.Return | JexlException.Cancel |
                     JexlException.Break | JexlException.Continue alterFlow) {
                flowControl = alterFlow;
            } catch (final JexlException exception) {
                // catching an exception thrown from catch body; can be a (re)throw
                rethrow = thrownByCatch = exception;
            }
        }
        // if we have a 'finally' block, no matter what, evaluate it: its control flow will
        // take precedence over what the 'catch' block might have thrown.
        if (node.hasFinallyClause()) {
            final JexlNode finallyBody = node.jjtGetChild(nc);
            try {
                finallyBody.jjtAccept(this, data);
            } catch (JexlException.Break | JexlException.Continue | JexlException.Return flowException) {
                // potentially swallow previous, even return but not cancel
                if (!(flowControl instanceof JexlException.Cancel)) {
                    flowControl = flowException;
                }
            } catch (final JexlException.Cancel cancelException) {
                // cancel swallows everything
                flowControl = cancelException;
            } catch (final JexlException exception) {
                // catching an exception thrown in finally body
                if (jexl.logger.isDebugEnabled()) {
                    jexl.logger.debug("exception thrown in finally", exception);
                }
                // swallow the caught one
                rethrow = exception;
            }
        }
        if (flowControl != null) {
            if (thrownByCatch != null && jexl.logger.isDebugEnabled()) {
                jexl.logger.debug("finally swallowed exception thrown by catch", thrownByCatch);
            }
            throw flowControl;
        }
        if (rethrow != null) {
            throw rethrow;
        }
        return result;
    }