spring webclient: retry with backoff on specific error

piotrek picture piotrek · Oct 23, 2019 · Viewed 12.7k times · Source

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

Answer

Alexander Pankin picture Alexander Pankin · Oct 23, 2019

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();
}