0

Is it possible to set RetryPolicy in spring retry based on error status code? e.g. I don't want to retry on HttpClientErrorException with HttpStatus.BAD_REQUEST status code, which is 400. Therefore it should ignore all other error codes -- 4XX.

I am using a Spring Integration http outboundGateway for invoking the server.

Right now in my RequestHandlerRetryAdvice I am configuring the my retry advice as

SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(4, Collections.singletonMap(HttpClientErrorException.class, false));

But this is too generic, I just don't want to retry on 400 Status code. For every other scenarios i want my template to retried. Can someone suggest me a solution here?

I went through stack overflow questions and i found one relevant answer but i didn't serve my purpose. Is it possible to set RetryPolicy in spring-retry based on HttpStatus status code?

Moulesh Kumar
  • 131
  • 2
  • 16
  • See the answer to the question you are duplicating. You definitely need the mentioned there `ExpressionRetryPolicy`. So, looks like your expression must be like `statusCode.value() != 400` – Artem Bilan Oct 11 '17 at 13:10

1 Answers1

4

I think you'd have to extend SimpleRetryPolicy to override the behaviour of:

public boolean canRetry(RetryContext context)

That method delegates to a BinaryExceptionClassifier to decide whether a given exception is retryable or not. That classifier makes its decision based on the exception type:

Classifies objects according to their inheritance relation with the supplied types. If the object to be classified is one of the provided types, or is a subclass of one of the types, then the non-default value is returned

Your customisation would make its decision based on HttpClientErrorException.getStatusCode(). Here's a crude approximation of it:

@Override
public boolean canRetry(RetryContext context) {
    Throwable t = context.getLastThrowable();
    if (HttpStatusCodeException.class.isAssignableFrom(t.getClass())) {
        HttpStatusCodeException httpStatusCodeException = (HttpStatusCodeException) t;
        if (httpStatusCodeException.getStatusCode() == HttpStatus.BAD_REQUEST) { 
            return false;   
        }
    }
    return super.canRetry(context);
}

A neater implementation would likely involve a custom implementation of org.springframework.classify.Classifier.

glytching
  • 44,936
  • 9
  • 114
  • 120
  • Ok so how do i get a retry context in the advice ? – Moulesh Kumar Oct 11 '17 at 11:30
  • The idea here is that would create your **own** retry policy i.e. create a class which extends `SimpleRetryPolicy` and override the `canRetry` method then update your `RequestHandlerRetryAdvice` ... SimpleRetryPolicy retryPolicy = new CustomRetryPolicy(4, Collections.singletonMap(HttpClientErrorException.class, false)); – glytching Oct 11 '17 at 11:33
  • Yeah, but my question is how do i get a retry context in the first place – Moulesh Kumar Oct 11 '17 at 11:50
  • As long as you are trying to use a `RetryContext` within an implementation of `SimpleRetryPolicy` Spring will take care of providing that to your policy. So, a few steps: (1) create your custom retry policy; (2) configure your `RequestHandlerRetryAdvice` to use your custom retry policy and once you have proven that your policy is being invoked then (3) tweak it until it behaves the way you want it to behave. – glytching Oct 11 '17 at 11:54