I added some functions to the JEXL engine wich can be used in the JEXL expressions:
Map<String, Object> functions = new HashMap<String, Object>();
mFunctions = new ConstraintFunctions();
functions.put(null, mFunctions);
mEngine.setFunctions(functions);
However, some functions can throw exceptions, for example:
public String chosen(String questionId) throws NoAnswerException {
Question<?> question = mQuestionMap.get(questionId);
SingleSelectAnswer<?> answer = (SingleSelectAnswer<?>) question.getAnswer();
if (answer == null) {
throw new NoAnswerException(question);
}
return answer.getValue().getId();
}
The custom function is called when i interpret an expression. The expression of course holds a call to this function:
String expression = "chosen('qID')";
Expression jexl = mEngine.createExpression(expression);
String questionId = (String) mExpression.evaluate(mJexlContext);
Unfortunetaly, when this function is called in course of interpretation, if it throws the NoAnswerException
, the interpreter does not propagete it to me, but throws a general JEXLException
. Is there any way to catch exceptions from custom functions? I use the apache commons JEXL engine for this, which is used as a library jar in my project.
After some investigation, i found an easy solution!
When an exception is thrown in a custom function, JEXL will throw a general JEXLException
. However, it smartly wraps the original exception in the JEXLException
, as it's cause in particular. So if we want to catch the original, we can write something like this:
try {
String questionId = (String) mExpression.evaluate(mJexlContext);
} catch (JexlException e) {
Exception original = e.getCause();
// do something with the original
}