From 028ff9b548666f80a55664367513b6b46fcd883c Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Tue, 9 Jul 2024 13:17:16 +0200 Subject: [PATCH] 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 --- .../expression/spel/ast/FunctionReference.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java index 0387b65ef33..0aeeee375b3 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java @@ -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 { 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) {