web-dev-qa-db-fra.com

Spring WebClient: Réessayer avec une boulotte sur une erreur spécifique

je voudrais réessayer la demande 3 fois après avoir attendu 10Sec lorsque la réponse est 5xx. Mais je ne vois pas une méthode que je peux utiliser. Sur l'objet

WebClient.builder()
                .baseUrl("...").build().post()
                .retrieve().bodyToMono(...)

je peux voir des méthodes:

réessayer sur la condition avec le nombre de tentatives mais pas de retard

.retry(3, {it is WebClientResponseException && it.statusCode.is5xxServerError} )

réessayer avec des backtes et le nombre de fois mais aucune condition

.retryBackoff 

il y a aussi un retryWhen mais je ne sais pas comment l'utiliser

7
piotrek

Avec le réacteur, vous pouvez le faire comme:

.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();
}
1
Alexander Pankin
// ...
.retryWhen(
    backoff(maxAttempts, minBackoff)
        .filter(throwable -> ((WebClientResponseException) throwable).getStatusCode().is5xxServerError()))
// ...
1
Sven Lange

la rétriguë avec réessayer.Tryof et réessayer.Onlyif sont obsolètes que je suppose. J'ai trouvé cette approche utile et cela nous permet de traiter et de lancer une exception définie par l'utilisateur.

par exemple :

retryWhen(Retry.backoff(3, Duration.of(2, ChronoUnit.SECONDS))
                        .filter(error -> error instanceof UserDefinedException/AnyOtherException)
                        .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) ->
                                new UserDefinedException(retrySignal.failure().getMessage())))
0
Sudharshan S.R.