Search code examples
javajava-8guava

How do I catch the exception thrown by the code inside a Guava retryer?


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!


Solution

  • 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);
    }