From 4651ab31d616bc5307b38787e325bcc74b74c24a Mon Sep 17 00:00:00 2001 From: puncleV Date: Wed, 6 Nov 2024 17:48:30 +0200 Subject: [PATCH 1/3] (refactor) make RetryException constructor public --- .../main/java/org/zalando/riptide/failsafe/RetryException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/riptide-failsafe/src/main/java/org/zalando/riptide/failsafe/RetryException.java b/riptide-failsafe/src/main/java/org/zalando/riptide/failsafe/RetryException.java index 7091b5b8d..3e6b858d0 100644 --- a/riptide-failsafe/src/main/java/org/zalando/riptide/failsafe/RetryException.java +++ b/riptide-failsafe/src/main/java/org/zalando/riptide/failsafe/RetryException.java @@ -11,7 +11,7 @@ @API(status = STABLE) public final class RetryException extends HttpResponseException { - RetryException(final ClientHttpResponse response) throws IOException { + public RetryException(final ClientHttpResponse response) throws IOException { super("Retrying response", response); } From f3459fd110017f1d4886a27a15becc529daa87a6 Mon Sep 17 00:00:00 2001 From: puncleV Date: Thu, 7 Nov 2024 15:56:46 +0200 Subject: [PATCH 2/3] (add) RetryException test case in autoconfigure package; --- .../autoconfigure/retry/FailsafeRetryTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/riptide-spring-boot-autoconfigure/src/test/java/org/zalando/riptide/autoconfigure/retry/FailsafeRetryTest.java b/riptide-spring-boot-autoconfigure/src/test/java/org/zalando/riptide/autoconfigure/retry/FailsafeRetryTest.java index da7ecedd1..4c0238d6d 100644 --- a/riptide-spring-boot-autoconfigure/src/test/java/org/zalando/riptide/autoconfigure/retry/FailsafeRetryTest.java +++ b/riptide-spring-boot-autoconfigure/src/test/java/org/zalando/riptide/autoconfigure/retry/FailsafeRetryTest.java @@ -13,14 +13,17 @@ import org.zalando.riptide.autoconfigure.MetricsTestAutoConfiguration; import org.zalando.riptide.autoconfigure.OpenTracingTestAutoConfiguration; import org.zalando.riptide.autoconfigure.RiptideClientTest; +import org.zalando.riptide.failsafe.RetryException; import java.util.concurrent.CompletionException; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.springframework.http.HttpStatus.Series.SERVER_ERROR; +import static org.springframework.http.HttpStatus.Series.CLIENT_ERROR; import static org.springframework.test.web.client.ExpectedCount.times; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockRestResponseCreators.withServerError; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withBadRequest; import static org.zalando.riptide.Bindings.on; import static org.zalando.riptide.Navigators.series; import static org.zalando.riptide.failsafe.RetryRoute.retry; @@ -54,4 +57,17 @@ void shouldRetryForAtMostMaxRetriesTimes() { server.verify(); } + + @Test + void shouldRetryForCustomRetryException() { + server.expect(times(3), requestTo("http://retry-test")).andRespond(withBadRequest()); + + + assertThrows(CompletionException.class, + () -> retryClient.get().dispatch(series(), on(CLIENT_ERROR).call(response -> { + throw new RetryException(response); + })).join()); + + server.verify(); + } } From ca62cc6bf76d038055fd364fb409ebde3d36b1dd Mon Sep 17 00:00:00 2001 From: puncleV Date: Thu, 7 Nov 2024 16:13:04 +0200 Subject: [PATCH 3/3] (docs) update readme with usage for `RetryException` --- riptide-failsafe/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/riptide-failsafe/README.md b/riptide-failsafe/README.md index 187e0d26a..ee08bc4f9 100644 --- a/riptide-failsafe/README.md +++ b/riptide-failsafe/README.md @@ -77,6 +77,23 @@ RetryPolicy.builder() .build(); ``` +By default, you can use RetryException in your routes to retry the request: + +```java +retryClient.get() + .dispatch( + series(), on(CLIENT_ERROR).call( + response -> { + if (specificCondition(response)) { + throw new RetryException(response); // we will retry this one + } else { + throw new AnyOtherException(response); // we wont retry this one + } + } + ) + ).join() +``` + Failsafe supports dynamically computed delays using a custom function. Riptide: Failsafe offers implementations that understand: