Browse Source

Improve error message for preemptive timeout in RetryTemplate

The error message in such cases now indicates that the retry process
is being aborted preemptively due to pending sleep time.

For example:

  Retry policy for operation 'myMethod' would exceed timeout (5 ms) due
  to pending sleep time (10 ms); preemptively aborting execution

See gh-35963
pull/35990/head
Sam Brannen 1 week ago
parent
commit
61201db704
  1. 8
      spring-core/src/main/java/org/springframework/core/retry/RetryTemplate.java
  2. 5
      spring-core/src/test/java/org/springframework/core/retry/RetryTemplateTests.java

8
spring-core/src/main/java/org/springframework/core/retry/RetryTemplate.java

@ -213,9 +213,13 @@ public class RetryTemplate implements RetryOperations { @@ -213,9 +213,13 @@ public class RetryTemplate implements RetryOperations {
// would be if we were to sleep for sleepTime milliseconds.
long elapsedTime = System.currentTimeMillis() + sleepTime - startTime;
if (elapsedTime >= timeout) {
RetryException retryException = new RetryException(
String message = (sleepTime > 0 ? """
Retry policy for operation '%s' would exceed timeout (%d ms) due \
to pending sleep time (%d ms); preemptively aborting execution"""
.formatted(retryable.getName(), timeout, sleepTime) :
"Retry policy for operation '%s' exceeded timeout (%d ms); aborting execution"
.formatted(retryable.getName(), timeout), exceptions.removeLast());
.formatted(retryable.getName(), timeout));
RetryException retryException = new RetryException(message, exceptions.removeLast());
exceptions.forEach(retryException::addSuppressed);
this.retryListener.onRetryPolicyTimeout(this.retryPolicy, retryable, retryException);
throw retryException;

5
spring-core/src/test/java/org/springframework/core/retry/RetryTemplateTests.java

@ -502,7 +502,10 @@ class RetryTemplateTests { @@ -502,7 +502,10 @@ class RetryTemplateTests {
assertThat(invocationCount).hasValue(0);
assertThatExceptionOfType(RetryException.class)
.isThrownBy(() -> retryTemplate.execute(retryable))
.withMessageMatching("Retry policy for operation '.+?' exceeded timeout \\(5 ms\\); aborting execution")
.withMessageMatching("""
Retry policy for operation '.+?' would exceed timeout \\(5 ms\\) \
due to pending sleep time \\(10 ms\\); preemptively aborting execution\
""")
.withCause(new CustomException("Boom 1"))
.satisfies(throwable -> inOrder.verify(retryListener).onRetryPolicyTimeout(
eq(retryPolicy), eq(retryable), eq(throwable)));

Loading…
Cancel
Save