Skip to content

Commit

Permalink
Merge pull request #726 from oliver-brm/main
Browse files Browse the repository at this point in the history
Make UniRetry & MultiRetry propagate the original Exception (#724)
  • Loading branch information
cescoffier committed Oct 13, 2021
2 parents 8c8b6e0 + 8a28b71 commit 43a6d66
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 20 deletions.
5 changes: 4 additions & 1 deletion documentation/src/test/java/guides/RetryTest.java
Expand Up @@ -38,7 +38,10 @@ public void testRetryWithBackoff() {
.withBackOff(Duration.ofMillis(100), Duration.ofSeconds(1))
.atMost(3);
// end::retry-backoff[]
assertThatThrownBy(() -> u.await().indefinitely()).hasMessageContaining("3/3");
assertThatThrownBy(() -> u.await().indefinitely())
.getCause() // Expected exception is wrapped in a java.util.concurrent.CompletionException
.hasMessageContaining("boom")
.hasSuppressedException(new IllegalStateException("Retries exhausted: 3/3"));
}

@Test
Expand Down
Expand Up @@ -41,14 +41,14 @@ public static Function<Multi<Throwable>, Publisher<Long>> randomExponentialBacko
.onItem().transformToUni(failure -> {
int iteration = index.getAndIncrement();
if (iteration >= numRetries) {
return Uni.createFrom().failure(
new IllegalStateException("Retries exhausted: " + iteration + "/" + numRetries,
failure));
failure.addSuppressed(
new IllegalStateException("Retries exhausted: " + iteration + "/" + numRetries, failure));
return Uni.createFrom().failure(failure);
} else {
Duration delay = getNextDelay(firstBackoff, maxBackoff, jitterFactor, iteration);
return Uni.createFrom().item((long) iteration).onItem().delayIt()
.onExecutor(executor).by(delay);
}

Duration delay = getNextDelay(firstBackoff, maxBackoff, jitterFactor, iteration);
return Uni.createFrom().item((long) iteration).onItem().delayIt()
.onExecutor(executor).by(delay);
}).concatenate();
}

Expand Down
@@ -1,6 +1,7 @@
package io.smallrye.mutiny.groups;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Assertions.assertThrows;

Expand Down Expand Up @@ -172,24 +173,22 @@ public void testExpireAtRetryWithBackOff() {

@Test
public void testRetryWithBackOffReachingMaxAttempt() {
assertThrows(IllegalStateException.class, () -> {
assertThatThrownBy(() -> {
AtomicInteger count = new AtomicInteger();
Uni.createFrom().<String> emitter(e -> {
e.fail(new Exception("boom " + count.getAndIncrement()));
})
Uni.createFrom().<String> emitter(e -> e.fail(new Exception("boom " + count.getAndIncrement())))
.onFailure().retry().withBackOff(Duration.ofMillis(10), Duration.ofSeconds(20)).withJitter(1.0)
.atMost(4)
.await().atMost(Duration.ofSeconds(5));
});
}).getCause() // Expected exception is wrapped in a java.util.concurrent.CompletionException
.hasMessageContaining("boom")
.hasSuppressedException(new IllegalStateException("Retries exhausted: 4/4"));
}

@Test
public void testRetryWithBackOffReachingExpiresIn() {
assertThrows(IllegalStateException.class, () -> {
AtomicInteger count = new AtomicInteger();
Uni.createFrom().<String> emitter(e -> {
e.fail(new Exception("boom " + count.getAndIncrement()));
})
Uni.createFrom().<String> emitter(e -> e.fail(new Exception("boom " + count.getAndIncrement())))
.onFailure().retry().withBackOff(Duration.ofMillis(10), Duration.ofSeconds(20)).withJitter(1.0)
.expireIn(90L)
.await().atMost(Duration.ofSeconds(5));
Expand Down
Expand Up @@ -299,7 +299,7 @@ public void testManualExponentialRetry() {
.subscribe().withSubscriber(AssertSubscriber.create(100));

subscriber
.await(Duration.ofSeconds(10))
.awaitCompletion(Duration.ofSeconds(10))
.assertItems("hey")
.assertCompleted();
}
Expand All @@ -319,7 +319,14 @@ public void testRetryWithRandomBackoff() {
await().until(() -> subscriber.getItems().size() >= 10);
subscriber
.assertItems(0, 1, 0, 1, 0, 1, 0, 1, 0, 1) // Initial subscription + 4 retries
.assertFailedWith(IllegalStateException.class, "Retries exhausted");
.assertFailedWith(IOException.class, "boom retry")
.awaitFailure(t -> {
// expecting an IllegalStateException with an info about the retries made
Throwable[] suppressed = exception.getSuppressed();
assertThat(suppressed.length).isEqualTo(1);
assertThat(suppressed).anyMatch(s -> s instanceof IllegalStateException &&
s.getMessage().equals("Retries exhausted: 4/4"));
});

}

Expand All @@ -336,7 +343,14 @@ public void testRetryWithRandomBackoffAndDefaultJitter() {
await().until(() -> subscriber.getItems().size() >= 10);
subscriber
.assertItems(0, 1, 0, 1, 0, 1, 0, 1, 0, 1) // Initial subscription + 4 retries
.assertFailedWith(IllegalStateException.class, "Retries exhausted: 4/4");
.assertFailedWith(IOException.class, "boom retry")
.awaitFailure(t -> {
// expecting an IllegalStateException with an info about the retries made
Throwable[] suppressed = exception.getSuppressed();
assertThat(suppressed.length).isEqualTo(1);
assertThat(suppressed).anyMatch(s -> s instanceof IllegalStateException &&
s.getMessage().equals("Retries exhausted: 4/4"));
});
}

@Test
Expand All @@ -353,7 +367,14 @@ public void testRetryWithDefaultMax() {
.until(() -> subscriber.getItems().size() >= 10);
subscriber
.assertItems(0, 1, 0, 1, 0, 1, 0, 1, 0, 1) // Initial subscription + 4 retries
.assertFailedWith(IllegalStateException.class, "Retries exhausted: 4/4");
.assertFailedWith(IOException.class, "boom retry")
.awaitFailure(t -> {
// expecting an IllegalStateException with an info about the retries made
Throwable[] suppressed = exception.getSuppressed();
assertThat(suppressed.length).isEqualTo(1);
assertThat(suppressed).anyMatch(s -> s instanceof IllegalStateException &&
s.getMessage().equals("Retries exhausted: 4/4"));
});
}

}

0 comments on commit 43a6d66

Please sign in to comment.