Skip to content
Advertisement

Spring retry exception handling execution behavior

I am trying to get to the best way to wrap spring-retry @Retryable annotation around external service call. Here is my code:

@Retryable(exclude = HttpClientErrorException.BadRequest.class, value = RestClientException.class)
private ResponseEntity<Item> retrieveItemById(String id) 
{
    HttpHeaders headers = new HttpHeaders();
    try {
        return restTemplate.exchange(httpConnectionProperties.getBaseUrl() + "/items",
                HttpMethod.GET, new HttpEntity<>(item, headers), Item.class, id);
    } 
    catch (RestClientException e) {
        log.error("Exception occurred while retrieving an item" , e);
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
}

I have a few questions on what happens when a RestClientException occurs :

  1. Is the catch block executed before retry kicks in or does the retry kicks in before the catch block execution? Do I need a recovery block?
  2. Probably more of an exception handling question – Is there a way to differentiate between an actual retry worthy scenario (service momentarily down, network issues, I/O error etc.) vs exception occurring due to lack of presence of an item in the above case?

Answer

Since you are catching and “handling” the exception, retry is disabled; retry will only work if the method throws an exception.

To change the result (instead of throwing the exception to the caller when retries are exhausted, you need a @Recover method.

Not retryable exceptions will go straight there; you can have multiple @Recover methods for different exception types, or one generic one and you can check the exception type yourself.

Advertisement