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 :
- 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? - 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?
Advertisement
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.