Skip to content

Commit

Permalink
Move failure handling Predicates to AbstractPolicy
Browse files Browse the repository at this point in the history
  • Loading branch information
jhalterman committed Dec 28, 2018
1 parent fbbe01e commit 4e92ec1
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 88 deletions.
58 changes: 54 additions & 4 deletions src/main/java/net/jodah/failsafe/AbstractPolicy.java
Expand Up @@ -6,6 +6,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.BiPredicate;

/**
Expand Down Expand Up @@ -64,7 +65,7 @@ public R handle(List<Class<? extends Throwable>> failures) {
Assert.notNull(failures, "failures");
Assert.isTrue(!failures.isEmpty(), "failures cannot be empty");
failuresChecked = true;
failureConditions.add(Predicates.failurePredicateFor(failures));
failureConditions.add(failurePredicateFor(failures));
return (R) this;
}

Expand All @@ -76,7 +77,7 @@ public R handle(List<Class<? extends Throwable>> failures) {
public R handleIf(Predicate<? extends Throwable> failurePredicate) {
Assert.notNull(failurePredicate, "failurePredicate");
failuresChecked = true;
failureConditions.add(Predicates.failurePredicateFor(failurePredicate));
failureConditions.add(failurePredicateFor(failurePredicate));
return (R) this;
}

Expand All @@ -97,7 +98,7 @@ public <T> R handleIf(BiPredicate<T, ? extends Throwable> resultPredicate) {
* Specifies that a failure has occurred if the {@code result} matches the execution result.
*/
public R handleResult(Object result) {
failureConditions.add(Predicates.resultPredicateFor(result));
failureConditions.add(resultPredicateFor(result));
return (R) this;
}

Expand All @@ -108,7 +109,7 @@ public R handleResult(Object result) {
*/
public <T> R handleResultIf(Predicate<T> resultPredicate) {
Assert.notNull(resultPredicate, "resultPredicate");
failureConditions.add(Predicates.resultPredicateFor(resultPredicate));
failureConditions.add(resultPredicateFor(resultPredicate));
return (R) this;
}

Expand Down Expand Up @@ -150,4 +151,53 @@ public boolean isFailure(Object result, Throwable failure) {
// Fail by default if a failure is not checked by a condition
return failure != null && !failuresChecked;
}

/**
* Returns a predicate that evaluates whether the {@code result} equals an execution result.
*/
static BiPredicate<Object, Throwable> resultPredicateFor(final Object result) {
return (t, u) -> Objects.equals(result, t);
}

/**
* Returns a predicate that evaluates the {@code failurePredicate} against a failure.
*/
@SuppressWarnings("unchecked")
static BiPredicate<Object, Throwable> failurePredicateFor(final Predicate<? extends Throwable> failurePredicate) {
return (t, u) -> u != null && ((Predicate<Throwable>) failurePredicate).test(u);
}

/**
* Returns a predicate that evaluates the {@code resultPredicate} against a result, when present.
*
* Short-circuts to false without invoking {@code resultPredicate},
* when result is not present (i.e. BiPredicate.test(null, Throwable)).
*/
@SuppressWarnings("unchecked")
static <T> BiPredicate<Object, Throwable> resultPredicateFor(final Predicate<T> resultPredicate) {
return (t, u) -> {
if (u == null) {
return ((Predicate<Object>) resultPredicate).test(t);
} else {
// resultPredicate is only defined over the success type.
// It doesn't know how to handle a failure of type Throwable,
// so we return false here.
return false;
}
};
}

/**
* Returns a predicate that returns whether any of the {@code failures} are assignable from an execution failure.
*/
static BiPredicate<Object, Throwable> failurePredicateFor(final List<Class<? extends Throwable>> failures) {
return (t, u) -> {
if (u == null)
return false;
for (Class<? extends Throwable> failureType : failures)
if (failureType.isAssignableFrom(u.getClass()))
return true;
return false;
};
}
}
78 changes: 0 additions & 78 deletions src/main/java/net/jodah/failsafe/Predicates.java

This file was deleted.

8 changes: 4 additions & 4 deletions src/main/java/net/jodah/failsafe/RetryPolicy.java
Expand Up @@ -141,7 +141,7 @@ public <T> RetryPolicy abortIf(BiPredicate<T, ? extends Throwable> completionPre
*/
public <T> RetryPolicy abortIf(Predicate<T> resultPredicate) {
Assert.notNull(resultPredicate, "resultPredicate");
abortConditions.add(Predicates.resultPredicateFor(resultPredicate));
abortConditions.add(resultPredicateFor(resultPredicate));
return this;
}

Expand Down Expand Up @@ -181,7 +181,7 @@ public RetryPolicy abortOn(Class<? extends Throwable>... failures) {
public RetryPolicy abortOn(List<Class<? extends Throwable>> failures) {
Assert.notNull(failures, "failures");
Assert.isTrue(!failures.isEmpty(), "failures cannot be empty");
abortConditions.add(Predicates.failurePredicateFor(failures));
abortConditions.add(failurePredicateFor(failures));
return this;
}

Expand All @@ -192,15 +192,15 @@ public RetryPolicy abortOn(List<Class<? extends Throwable>> failures) {
*/
public RetryPolicy abortOn(Predicate<? extends Throwable> failurePredicate) {
Assert.notNull(failurePredicate, "failurePredicate");
abortConditions.add(Predicates.failurePredicateFor(failurePredicate));
abortConditions.add(failurePredicateFor(failurePredicate));
return this;
}

/**
* Specifies that retries should be aborted if the execution result matches the {@code result}.
*/
public RetryPolicy abortWhen(Object result) {
abortConditions.add(Predicates.resultPredicateFor(result));
abortConditions.add(resultPredicateFor(result));
return this;
}

Expand Down
Expand Up @@ -21,9 +21,9 @@
import java.util.function.BiPredicate;

@Test
public class PredicatesTest {
public class AbstractPolicyTest {
public void testResultPredicateOnlyHandlesResults() {
BiPredicate<Object, Throwable> resultPredicate = Predicates.resultPredicateFor(result -> true);
BiPredicate<Object, Throwable> resultPredicate = AbstractPolicy.resultPredicateFor(result -> true);
Assert.assertTrue(resultPredicate.test("result", null));
Assert.assertFalse(resultPredicate.test(null, new RuntimeException()));
}
Expand Down

0 comments on commit 4e92ec1

Please sign in to comment.