Strong typing

Failsafe APIs are typed based on the expected execution result. For generic policies that are used for various executions, the result type may just be Object:

RetryPolicy<Object> retryPolicy = RetryPolicy.ofDefaults(); 

But for other policies you might declare a more specific result type:

RetryPolicy<HttpResponse> retryPolicy = RetryPolicy.<HttpResponse>builder() .handleResultIf(response -> response.getStatusCode() == 500) .onFailedAttempt(e -> log.warn("Failed attempt: {}", e.getLastResult().getStatusCode())) .build(); 

This allows Failsafe to ensure that the same result type used for the policy is returned by the execution and available in event listeners:

HttpResponse response = Failsafe.with(retryPolicy) .onSuccess(e -> log.info("Success: {}", e.getResult().getStatusCode())) .get(this::sendHttpRequest); 

It also ensures that when multiple policies are composed, they all share the same result type:

CircuitBreaker<HttpResponse> circuitBreaker = CircuitBreaker.ofDefaults(); Failsafe.with(retryPolicy, circuitBreaker).get(this::connect);