Skip to content

Commit 052d55f

Browse files
committed
Add a typed parameter for the failure in FailurePolicy.handleIf
1 parent c285214 commit 052d55f

File tree

4 files changed

+47
-24
lines changed

4 files changed

+47
-24
lines changed

src/main/java/net/jodah/failsafe/Failsafe.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ public class Failsafe {
3636
* Failsafe.with(fallback, retryPolicy, circuitBreaker).get(supplier);
3737
* </pre>
3838
* </p>
39-
* This results in the following internal composition when executing the {@code supplier} and handling its result:
39+
* This results in the following internal composition when executing a {@code runnable} or {@code supplier} and
40+
* handling its result:
4041
* <p>
4142
* <pre>
4243
* Fallback(RetryPolicy(CircuitBreaker(Supplier)))
@@ -65,10 +66,11 @@ public static <R, P extends Policy<R>> FailsafeExecutor<R> with(P outerPolicy, P
6566
* the last policy being applied first. For example, consider:
6667
* <p>
6768
* <pre>
68-
* Failsafe.with(fallback, retryPolicy, circuitBreaker).get(supplier);
69+
* Failsafe.with(Arrays.asList(fallback, retryPolicy, circuitBreaker)).get(supplier);
6970
* </pre>
7071
* </p>
71-
* This results in the following internal composition when executing the {@code supplier} and handling its result:
72+
* This results in the following internal composition when executing a {@code runnable} or {@code supplier} and
73+
* handling its result:
7274
* <p>
7375
* <pre>
7476
* Fallback(RetryPolicy(CircuitBreaker(Supplier)))

src/main/java/net/jodah/failsafe/FailurePolicy.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
/**
2828
* A Policy that captures conditions to determine whether an execution is a failure.
2929
* <p>
30-
* If no handlers are configured, the execution is considered a failure if an Exception was thrown.
30+
* By default, if no handlers are configured, the execution is considered a failure if an Exception was thrown. If
31+
* multuple handlers are configured, they are logically OR'ed.
3132
* </p>
3233
*
3334
* @param <S> self type
@@ -84,9 +85,10 @@ public S handle(List<Class<? extends Throwable>> failures) {
8485
/**
8586
* Specifies that a failure has occurred if the {@code failurePredicate} matches the failure.
8687
*
88+
* @param <T> failure type
8789
* @throws NullPointerException if {@code failurePredicate} is null
8890
*/
89-
public S handleIf(Predicate<? extends Throwable> failurePredicate) {
91+
public <T extends Throwable> S handleIf(Predicate<T> failurePredicate) {
9092
Assert.notNull(failurePredicate, "failurePredicate");
9193
failuresChecked = true;
9294
failureConditions.add(failurePredicateFor(failurePredicate));
@@ -96,10 +98,11 @@ public S handleIf(Predicate<? extends Throwable> failurePredicate) {
9698
/**
9799
* Specifies that a failure has occurred if the {@code resultPredicate} matches the execution result.
98100
*
101+
* @param <T> failure type
99102
* @throws NullPointerException if {@code resultPredicate} is null
100103
*/
101104
@SuppressWarnings("unchecked")
102-
public S handleIf(BiPredicate<R, ? extends Throwable> resultPredicate) {
105+
public <T extends Throwable> S handleIf(BiPredicate<R, T> resultPredicate) {
103106
Assert.notNull(resultPredicate, "resultPredicate");
104107
failuresChecked = true;
105108
failureConditions.add((BiPredicate<R, Throwable>) resultPredicate);

src/test/java/net/jodah/failsafe/RetryPolicyTest.java

+33-15
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,22 @@
2727

2828
@Test
2929
public class RetryPolicyTest {
30+
static class FooException extends Exception {
31+
String bar;
32+
33+
FooException(String bar) {
34+
this.bar = bar;
35+
}
36+
}
37+
3038
public void testIsFailureNull() {
3139
RetryPolicy<Object> policy = new RetryPolicy<>();
3240
assertFalse(policy.isFailure(null, null));
3341
}
3442

3543
public void testIsFailureCompletionPredicate() {
36-
RetryPolicy<Object> policy = new RetryPolicy<>()
37-
.handleIf((result, failure) -> result == "test" || failure instanceof IllegalArgumentException);
44+
RetryPolicy<Object> policy = new RetryPolicy<>().handleIf(
45+
(result, failure) -> result == "test" || failure instanceof IllegalArgumentException);
3846
assertTrue(policy.isFailure("test", null));
3947
// No retries needed for successful result
4048
assertFalse(policy.isFailure(0, null));
@@ -48,6 +56,12 @@ public void testIsFailureFailurePredicate() {
4856
assertFalse(policy.isFailure(null, new IllegalStateException()));
4957
}
5058

59+
public void testIsFailureTypedFailurePredicate() {
60+
RetryPolicy<Boolean> policy = new RetryPolicy<Boolean>().<FooException>handleIf((result, failure) -> failure.bar.equals("bar"));
61+
assertTrue(policy.isFailure(null, new FooException("bar")));
62+
assertFalse(policy.isFailure(null, new IllegalStateException()));
63+
}
64+
5165
public void testIsFailureResultPredicate() {
5266
RetryPolicy<Integer> policy = new RetryPolicy<Integer>().handleResultIf(result -> result > 100);
5367
assertTrue(policy.isFailure(110, null));
@@ -93,8 +107,8 @@ public void testIsAbortableNull() {
93107
}
94108

95109
public void testIsAbortableCompletionPredicate() {
96-
RetryPolicy<Object> policy = new RetryPolicy<>()
97-
.abortIf((result, failure) -> result == "test" || failure instanceof IllegalArgumentException);
110+
RetryPolicy<Object> policy = new RetryPolicy<>().abortIf(
111+
(result, failure) -> result == "test" || failure instanceof IllegalArgumentException);
98112
assertTrue(policy.isAbortable("test", null));
99113
assertFalse(policy.isAbortable(0, null));
100114
assertTrue(policy.isAbortable(null, new IllegalArgumentException()));
@@ -142,19 +156,23 @@ public void testIsAbortableResult() {
142156
public void shouldRequireValidBackoff() {
143157
Asserts.assertThrows(() -> new RetryPolicy().withBackoff(0, 0, null), NullPointerException.class);
144158
Asserts.assertThrows(
145-
() -> new RetryPolicy().withMaxDuration(Duration.ofMillis(1)).withBackoff(100, 120, ChronoUnit.MILLIS),
146-
IllegalStateException.class);
147-
Asserts.assertThrows(() -> new RetryPolicy().withBackoff(-3, 10, ChronoUnit.MILLIS), IllegalArgumentException.class);
148-
Asserts.assertThrows(() -> new RetryPolicy().withBackoff(100, 10, ChronoUnit.MILLIS), IllegalArgumentException.class);
149-
Asserts.assertThrows(() -> new RetryPolicy().withBackoff(5, 10, ChronoUnit.MILLIS, .5), IllegalArgumentException.class);
159+
() -> new RetryPolicy().withMaxDuration(Duration.ofMillis(1)).withBackoff(100, 120, ChronoUnit.MILLIS),
160+
IllegalStateException.class);
161+
Asserts.assertThrows(() -> new RetryPolicy().withBackoff(-3, 10, ChronoUnit.MILLIS),
162+
IllegalArgumentException.class);
163+
Asserts.assertThrows(() -> new RetryPolicy().withBackoff(100, 10, ChronoUnit.MILLIS),
164+
IllegalArgumentException.class);
165+
Asserts.assertThrows(() -> new RetryPolicy().withBackoff(5, 10, ChronoUnit.MILLIS, .5),
166+
IllegalArgumentException.class);
150167
}
151168

152169
public void shouldRequireValidDelay() {
153-
Asserts.assertThrows(() -> new RetryPolicy().withDelay((Duration)null), NullPointerException.class);
154-
Asserts.assertThrows(() -> new RetryPolicy().withMaxDuration(Duration.ofMillis(1)).withDelay(Duration.ofMillis(100)),
155-
IllegalStateException.class);
170+
Asserts.assertThrows(() -> new RetryPolicy().withDelay((Duration) null), NullPointerException.class);
171+
Asserts.assertThrows(
172+
() -> new RetryPolicy().withMaxDuration(Duration.ofMillis(1)).withDelay(Duration.ofMillis(100)),
173+
IllegalStateException.class);
156174
Asserts.assertThrows(() -> new RetryPolicy().withBackoff(1, 2, ChronoUnit.MILLIS).withDelay(Duration.ofMillis(100)),
157-
IllegalStateException.class);
175+
IllegalStateException.class);
158176
Asserts.assertThrows(() -> new RetryPolicy().withDelay(Duration.ofMillis(-1)), IllegalArgumentException.class);
159177
}
160178

@@ -164,8 +182,8 @@ public void shouldRequireValidMaxRetries() {
164182

165183
public void shouldRequireValidMaxDuration() {
166184
Asserts.assertThrows(
167-
() -> new RetryPolicy().withDelay(Duration.ofMillis(100)).withMaxDuration(Duration.ofMillis(100)),
168-
IllegalStateException.class);
185+
() -> new RetryPolicy().withDelay(Duration.ofMillis(100)).withMaxDuration(Duration.ofMillis(100)),
186+
IllegalStateException.class);
169187
}
170188

171189
public void testGetMaxAttempts() {

src/test/java/net/jodah/failsafe/examples/VertxExample.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ public class VertxExample {
3030
static Vertx vertx = Vertx.vertx();
3131

3232
/** Create RetryPolicy to handle Vert.x failures */
33-
static RetryPolicy<Object> retryPolicy = new RetryPolicy<>().handleIf(
34-
(ReplyException failure) -> ReplyFailure.RECIPIENT_FAILURE.equals(failure.failureType())
35-
|| ReplyFailure.TIMEOUT.equals(failure.failureType()));
33+
static RetryPolicy<Object> retryPolicy = new RetryPolicy<>().<ReplyException>handleIf(
34+
failure -> ReplyFailure.RECIPIENT_FAILURE.equals(failure.failureType()) || ReplyFailure.TIMEOUT.equals(
35+
failure.failureType()));
3636

3737
/** Adapt Vert.x timer to a Failsafe Scheduler */
3838
static Scheduler scheduler = (callable, delay, unit) -> {

0 commit comments

Comments
 (0)