i'd like to retry the request 3 times after waiting 10sec when response is 5xx. but i don't see a method that I can use. On object
WebClient.builder()
                .baseUrl("...").build().post()
                .retrieve().bodyToMono(...)
i can see methods:
retrying on condition with retry count but no delay
.retry(3, {it is WebClientResponseException && it.statusCode.is5xxServerError} )
retrying with backoff and number of times but no condition
.retryBackoff 
there is also a retryWhen but i'm not sure how to use it
With reactor-extra you could do it like:
.retryWhen(Retry.onlyIf(this::is5xxServerError)
        .fixedBackoff(Duration.ofSeconds(10))
        .retryMax(3))
private boolean is5xxServerError(RetryContext<Object> retryContext) {
    return retryContext.exception() instanceof WebClientResponseException &&
            ((WebClientResponseException) retryContext.exception()).getStatusCode().is5xxServerError();
}
Update: With new API the same solution will be:
    .retryWhen(Retry.fixedDelay(3, Duration.ofSeconds(10))
            .filter(this::is5xxServerError));
//...
private boolean is5xxServerError(Throwable throwable) {
    return throwable instanceof WebClientResponseException &&
            ((WebClientResponseException) throwable).getStatusCode().is5xxServerError();
}
                        You can do this taking the following approach:
exchange() method to obtain the response without an exception, and then throw a specific (custom) exception on a 5xx response (this differs from retrieve() which will always throw WebClientResponseException with either a 4xx or 5xx status);reactor-extra - it contains a nice way to use retryWhen() for more complex & specific retries. You can then specify a random backoff retry that starts after 10 seconds, goes up to an arbitrary time and tries a maximum of 3 times. (Or you can use the other available methods to pick a different strategy of course.)For example:
//...webclient
.exchange()
.flatMap(clientResponse -> {
    if (clientResponse.statusCode().is5xxServerError()) {
        return Mono.error(new ServerErrorException());
    } else {
        //Any further processing
    }
}).retryWhen(
    Retry.anyOf(ServerErrorException.class)
       .randomBackoff(Duration.ofSeconds(10), Duration.ofHours(1))
       .maxRetries(3)
    )
);
                        the retryWhen with Retry.anyOf and Retry.onlyIf are deprecated I assume. I found this approach useful, and it allows us to process and throw a User defined exception.
for example :
retryWhen(Retry.backoff(3, Duration.of(2, ChronoUnit.SECONDS))
                        .filter(error -> error instanceof UserDefinedException/AnyOtherException)
                        .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) ->
                                new UserDefinedException(retrySignal.failure().getMessage())))
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With