Is it possible to set RetryPolicy in spring retry (https://github.com/spring-projects/spring-retry) based on error status code? e.g. I want to retry on HttpServerErrorException
with HttpStatus.INTERNAL_SERVER_ERROR
status code, which is 503. Therefore it should ignore all other error codes -- [500 - 502] and [504 - 511].
Asked
Active
Viewed 1.5k times
13

Marat Kurbanov
- 197
- 1
- 2
- 10
-
Not directly, but if you can provide much more context of how you are invoking the server (for example, if you are using a Spring Integration outbound gateway or whether you are using `RestTemplate` directly from your code), we might be able to suggest a solution. – Gary Russell Dec 01 '14 at 21:26
-
I extended RestTemplate and did overrided a few methods surrounding them with RetryTemplate. I am following an example given on the github link above, similar to... SimpleRetryPolicy policy = new SimpleRetryPolicy(); policy.setMaxAttempts(5); policy.setRetryableExceptions(new Class[] {HttpServerErrorException.class}); Spring restTemplate reports 'HttpServerErrorException.class' for http status error codes 500 - 511 but, I want to retry on 503 and 504. – Marat Kurbanov Dec 02 '14 at 03:50
-
For now, I am pulling throwable from RetryContext in doWithRetry(RetryContext context) and reading the error message - context.getLastThrowable().getMessage(), then looking for either 503 or 504. There has to be a better way to do it, I think. – Marat Kurbanov Dec 02 '14 at 03:50
-
@MaratKurbanov , can you please help us to do the same , of retrying based on specific http status codes – Bravo Jun 28 '17 at 08:52
-
@GaryRussell I am using Spring Integration outbound gateway for invoking the server. Can you please suggest a solution ? – Moulesh Kumar Oct 10 '17 at 15:20
-
You should really ask a new question rather than commenting on an old one. Add a [retry request handler advice](https://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#message-handler-advice-chain) with an appropriately configured retry template. – Gary Russell Oct 10 '17 at 16:13
3 Answers
9
The RestTemplate
has setErrorHandler
option and DefaultResponseErrorHandler
is the default one.
Its code looks like:
public void handleError(ClientHttpResponse response) throws IOException {
HttpStatus statusCode = getHttpStatusCode(response);
switch (statusCode.series()) {
case CLIENT_ERROR:
throw new HttpClientErrorException(statusCode, response.getStatusText(),
response.getHeaders(), getResponseBody(response), getCharset(response));
case SERVER_ERROR:
throw new HttpServerErrorException(statusCode, response.getStatusText(),
response.getHeaders(), getResponseBody(response), getCharset(response));
default:
throw new RestClientException("Unknown status code [" + statusCode + "]");
}
}
So, you can provide your own implementation for that method to simplify your RetryPolicy
around desired status codes.

Artem Bilan
- 113,505
- 11
- 91
- 118
9
For others who are facing same problem, I'm posting this answer. Implement custom retry policy as follows:
class InternalServerExceptionClassifierRetryPolicy extends ExceptionClassifierRetryPolicy {
public InternalServerExceptionClassifierRetryPolicy() {
final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
simpleRetryPolicy.setMaxAttempts(3);
this.setExceptionClassifier(new Classifier<Throwable, RetryPolicy>() {
@Override
public RetryPolicy classify(Throwable classifiable) {
if (classifiable instanceof HttpServerErrorException) {
// For specifically 500 and 504
if (((HttpServerErrorException) classifiable).getStatusCode() == HttpStatus.INTERNAL_SERVER_ERROR
|| ((HttpServerErrorException) classifiable)
.getStatusCode() == HttpStatus.GATEWAY_TIMEOUT) {
return simpleRetryPolicy;
}
return new NeverRetryPolicy();
}
return new NeverRetryPolicy();
}
});
}}
Ans the simply call it as below:
RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(new InternalServerExceptionClassifierRetryPolicy())

VaibS
- 1,627
- 1
- 15
- 21
-
Just one important note that took me some time to figure it out + debug. The policy has to be created outside the lambda just as in the example (i.e. do not try to do return New SimpleRetryPolicy(3) in the inner if), because if not it enters into infinite loop (i.e. do not obey the max attempts). Hope it helps. – Ignacio Apr 03 '20 at 19:42
-
Did the same thing but not working. the below autowing picking simpleretry inspite of returning neverretry from InternalServerExceptionClassifierRetryPolicy class @Autowired RetryTemplate retryTemplate; – VIJ Jul 18 '22 at 12:56
0
You can also add the specific error code in the retryableExceptions list of the SinmpleRetryPolicy.
Map<Class<? extends Throwable>, Boolean> retryableExceptions = new HashMap<>();
retryableExceptions.put(HttpClientErrorException.Unauthorized.class, true);
retryTemplate.setRetryPolicy(new SimpleRetryPolicy(5, retryableExceptions));

kuyu
- 352
- 3
- 11