GH-405: Re-throw as is after recoverer
Fixes: #405 The unchecked exception is wrapped into `UndeclaredThrowableException` if `recoverer` is in use; it is not otherwise * Fix `RetryTemplate` to catch `UndeclaredThrowableException` from `recoveryCallback.recover()` and re-throw its `cause` instead to re-align behavior when no recoverer provided
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.retry.support;
|
||||
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -545,9 +546,14 @@ public class RetryTemplate implements RetryOperations {
|
||||
boolean doRecover = !Boolean.TRUE.equals(context.getAttribute(RetryContext.NO_RECOVERY));
|
||||
if (recoveryCallback != null) {
|
||||
if (doRecover) {
|
||||
T recovered = recoveryCallback.recover(context);
|
||||
context.setAttribute(RetryContext.RECOVERED, true);
|
||||
return recovered;
|
||||
try {
|
||||
T recovered = recoveryCallback.recover(context);
|
||||
context.setAttribute(RetryContext.RECOVERED, true);
|
||||
return recovered;
|
||||
}
|
||||
catch (UndeclaredThrowableException undeclaredThrowableException) {
|
||||
throw wrapIfNecessary(undeclaredThrowableException.getUndeclaredThrowable());
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.debug("Retry exhausted and recovery disabled for this throwable");
|
||||
|
||||
@@ -190,6 +190,9 @@ public class EnableRetryTests {
|
||||
service.setExceptionToThrow(new IllegalArgumentException());
|
||||
service.service();
|
||||
assertThat(service.getCount()).isEqualTo(3);
|
||||
|
||||
assertThatExceptionOfType(InstantiationException.class).isThrownBy(service::reThrowAsIs).withMessage("noRetry");
|
||||
|
||||
context.close();
|
||||
}
|
||||
|
||||
@@ -750,6 +753,16 @@ public class EnableRetryTests {
|
||||
this.exceptionToThrow = exceptionToThrow;
|
||||
}
|
||||
|
||||
@Retryable(noRetryFor = InstantiationException.class, recover = "noRetryRecovery")
|
||||
public void reThrowAsIs() throws InstantiationException {
|
||||
throw new InstantiationException("noRetry");
|
||||
}
|
||||
|
||||
@Recover
|
||||
public void noRetryRecovery(Throwable ex) throws Throwable {
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class StatefulService {
|
||||
|
||||
Reference in New Issue
Block a user