I have a retryable REST call which retries on specific cases. Currently, it retries even on read timeout & connection timeout scenario as well.
@Retryable(value = {RestClientException.class},maxAttempts = 2,
exclude = {HttpClientErrorException.BadRequest.class})
public ResponseEntity<String> testMethod() throws Exception {
return restTemplateRtp.exchange("http://localhost:8080/api/test", HttpMethod.POST, request, String.class);
}
In case of a readtimeout, the retry retries for 2 times, and then fails with this exception:
org.springframework.web.client.ResourceAccessException: I/O error
on POST request for "http://localhost:8080/api/test": Read timed
out; nested exception is java.net.SocketTimeoutException: Read timed out
I dont want to retry on read timeout but want the retry to continue for connect timeout. When I try to add SocketTimeoutException
in the exclude
, its still retrying for read timeout as well.
How to handle this scenario? I cant add ResourceAccessException
to the exclude
, then both the read & connect timeouts will stop getting retried.
From the exception stack trace i can say the ResourceAccessException
is top level exception that is thrown due to underlying java.net.SocketTimeoutException
.
and, from the java-docs socket timeout will be thrown on multiple use cases
Signals that a timeout has occurred on a socket read or accept.
If would suggest adding custom logic for excluding any underlying exceptions
@Retryable(value = {RestClientException.class},maxAttempts = 2,
exclude = {HttpClientErrorException.BadRequest.class})
public ResponseEntity<String> testMethod() throws Exception {
try {
return restTemplateRtp.exchange("http://localhost:8080/api/test", HttpMethod.POST, request, String.class);
}catch(ResourceAccessException ex) {
if(ex.getCause() instanceOf java.net.SocketTimeoutException
&& ex.getCause().getMessage().equals("Read timed out")) {
//exclude don't retry and return something
}
// else throw ex;
}
}
}