I want to perform an action that can be retried for a maximum of three times. I use the Failsafe library to implement a RetryPolicy
as shown below:
private static FailsafeExecutor<List<String>> includeFailsafe() {
RetryPolicy<List<String>> retryPolicy = RetryPolicy.<List<String>>builder()
.handleResultIf(Predicate.not(List::isEmpty))
.withMaxAttempts(MAX_RETRIES)
.withBackoff(Duration.ofMillis(200L), Duration.ofMillis(4000L))
.onFailedAttempt(e -> log.warn("some warning message"))
.onRetriesExceeded(e -> log.error("some error message"))
.build();
Fallback<List<String>> fallback = Fallback.ofException(e -> new Exception());
return Failsafe.with(fallback, retryPolicy);
}
Failsafe is then used for the following method:
private void publishIncludeFailsafe(List<String> x) {
includeFailsafe().get(ctx -> {
List<String> input = ctx.isRetry() ? ctx.getLastResult() : x;
PublishBatchResponse response = publishBatch(input);
if (response.hasFailed()) {
return response.failed().stream().map(BatchResultErrorEntry::message).toList();
}
return List.of();
});
}
I use a unit test to mock the behavior when all retries fail, and I can see the error message that is logged when retries have been exceeded. So far, this seems to work.
However, I want to throw a custom exception when this scenario occurs through a fallback. However, the fallback is never triggered and it seems like I am doing something wrong here.
Why is the fallback never 'triggered' after retries have exceeded their maximum? And how can I still manage to throw the exception?