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?
CodePudding user response:
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.