From cc4c693db7d7f713f106c8fb534290e6227440f3 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Tue, 9 Dec 2025 16:24:00 +0100 Subject: [PATCH] Log RetryException for @Retryable methods To improve diagnostics, this commit logs a DEBUG message including the RetryException thrown by RetryTemplate when it's used behind the scenes for @Retryable method invocations. Closes gh-35983 --- .../resilience/retry/AbstractRetryInterceptor.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/spring-context/src/main/java/org/springframework/resilience/retry/AbstractRetryInterceptor.java b/spring-context/src/main/java/org/springframework/resilience/retry/AbstractRetryInterceptor.java index 4f8f1793302..6b3bc7f40a5 100644 --- a/spring-context/src/main/java/org/springframework/resilience/retry/AbstractRetryInterceptor.java +++ b/spring-context/src/main/java/org/springframework/resilience/retry/AbstractRetryInterceptor.java @@ -22,6 +22,8 @@ import java.util.concurrent.Future; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; @@ -50,6 +52,8 @@ import org.springframework.util.ClassUtils; */ public abstract class AbstractRetryInterceptor implements MethodInterceptor { + private static final Log logger = LogFactory.getLog(AbstractRetryInterceptor.class); + /** * Reactive Streams API present on the classpath? */ @@ -102,6 +106,7 @@ public abstract class AbstractRetryInterceptor implements MethodInterceptor { .maxDelay(spec.maxDelay()) .build(); RetryTemplate retryTemplate = new RetryTemplate(retryPolicy); + String methodName = ClassUtils.getQualifiedMethodName(method, (target != null ? target.getClass() : null)); try { return retryTemplate.execute(new Retryable<@Nullable Object>() { @@ -112,11 +117,14 @@ public abstract class AbstractRetryInterceptor implements MethodInterceptor { } @Override public String getName() { - return ClassUtils.getQualifiedMethodName(method, (target != null ? target.getClass() : null)); + return methodName; } }); } catch (RetryException ex) { + if (logger.isDebugEnabled()) { + logger.debug("@Retryable operation '%s' failed".formatted(methodName), ex); + } throw ex.getCause(); } }