Browse Source

Unwrap InvocationTargetException in SpEL's FunctionReference

FunctionReference in the Spring Expression Language (SpEL) currently
does not unwrap an InvocationTargetException; however,
ConstructorReference and MethodReference do.

For example, currently one may encounter an exception like the
following, where the 'null' comes from the fact that an
InvocationTargetException doesn't always have a message.

SpelEvaluationException: EL1023E: A problem occurred whilst attempting
  to invoke the function 'formatObjectVarargs': 'null'

To address that, and to align with the behavior of ConstructorReference
and MethodReference, this commit modifies FunctionReference so that it
unwraps the InvocationTargetException to use its cause for the
exception message, resulting in an exception message like the following.

SpelEvaluationException: EL1023E: A problem occurred whilst attempting
  to invoke the function 'formatObjectVarargs': 'Format specifier '%s''

Closes gh-33174
pull/33181/head
Sam Brannen 1 year ago
parent
commit
028ff9b548
  1. 7
      spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java

7
spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java

@ -18,6 +18,7 @@ package org.springframework.expression.spel.ast; @@ -18,6 +18,7 @@ package org.springframework.expression.spel.ast;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.StringJoiner;
@ -145,8 +146,10 @@ public class FunctionReference extends SpelNodeImpl { @@ -145,8 +146,10 @@ public class FunctionReference extends SpelNodeImpl {
return new TypedValue(result, new TypeDescriptor(new MethodParameter(method, -1)).narrow(result));
}
catch (Exception ex) {
throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.EXCEPTION_DURING_FUNCTION_CALL,
this.name, ex.getMessage());
Throwable cause = ((ex instanceof InvocationTargetException ite && ite.getCause() != null) ?
ite.getCause() : ex);
throw new SpelEvaluationException(getStartPosition(), cause, SpelMessage.EXCEPTION_DURING_FUNCTION_CALL,
this.name, cause.getMessage());
}
finally {
if (compilable) {

Loading…
Cancel
Save