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;
}