I have a Guava retryer around some code:
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfExceptionOfType(Exception.class)
.withStopStrategy(MoreStopStrategies.liveStopAfterAttempt(retries))
.withWaitStrategy(MoreWaitStrategies.liveExponentialWait(TimeUnit.MILLISECONDS, retrySleep, TimeUnit.MILLISECONDS))
.build();
try {
retryer.call(() -> {
return doStuff();
});
} catch (ExecutionException | RetryException e) {
throw Throwables.propagate(e);
}
Let's say doStuff()
throws an ArithmeticException
. How do I catch that outside the retryer.call()
?
So the retryer will try a couple times, fail, and enter into the catch (ExecutionException | RetryException e)
block. How would I retrieve the ArithmeticException
inside there?
Thanks!
This is a bit of a faulty pattern. You say that any exception is ok to retry. An ArithmeticException
will then be ok to retry. This is not what you want.
This is how retries should be implemented. Note the comment on the second line.
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
// .retryIfExceptionOfType(Exception.class)
.withStopStrategy(MoreStopStrategies.liveStopAfterAttempt(retries))
.withWaitStrategy(MoreWaitStrategies.liveExponentialWait(TimeUnit.MILLISECONDS, retrySleep, TimeUnit.MILLISECONDS))
.build();
void doStuff() {
try {
retryer.call(() -> {
doRealStuff();
});
} catch (RetryException e) {
throw new RuntimeException("Call never succeeded", e);
} catch (ExecutionException e) {
Throwables.propagateIfPossible(e.getCause(), ArithmeticException.class);
throw new RuntimeException("Unexpected", e);
}
}
Then when you actually call doStuff
:
try {
doStuff();
} catch(ArithmeticException e) {
System.err.println("Arithmetic exception caught:");
e.printStackTrace(System.err);
}