Skip to content

Commit

Permalink
Added Try.mapFailure(Case...) (#1924)
Browse files Browse the repository at this point in the history
  • Loading branch information
danieldietrich authored Mar 25, 2017
1 parent 755355d commit 237a3db
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
4 changes: 2 additions & 2 deletions javaslang/src/main/java/javaslang/collection/Traversable.java
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,8 @@ default T single() {
* Matches each element with a unique key that you extract from it.
* If the same key is present twice, the function will return {@code None}.
*
* @param classifier A function which extracts a key from elements
* @param <K> key class type
* @param getKey A function which extracts a key from elements
* @param <K> key class type
* @return A Map containing the elements arranged by their keys.
* @throws NullPointerException if {@code getKey} is null.
* @see #groupBy(Function)
Expand Down
18 changes: 18 additions & 0 deletions javaslang/src/main/java/javaslang/control/Try.java
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,24 @@ default <U> Try<U> map(Function<? super T, ? extends U> mapper) {
return mapTry(mapper::apply);
}

/**
* Maps the cause to a new exception if this is a {@code Failure} or returns this instance if this is a {@code Success}.
* <p>
* If none of the given cases matches the cause, the same {@code Failure} is returned.
*
* @param cases A not necessarily exhaustive sequence of cases that will be matched against a cause.
* @return A new {@code Try} if this is a {@code Failure}, otherwise this.
*/
@SuppressWarnings({ "unchecked", "varargs" })
default Try<T> mapFailure(Match.Case<? extends Throwable, ? extends Throwable>... cases) {
if (isSuccess()) {
return this;
} else {
final Option<Throwable> x = Match(getCause()).option(cases);
return x.isEmpty() ? this : failure(x.get());
}
}

/**
* Runs the given checked function if this is a {@code Success},
* passing the result of the current expression to it.
Expand Down
36 changes: 34 additions & 2 deletions javaslang/src/test/java/javaslang/control/TryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
*/
package javaslang.control;

import static javaslang.API.Failure;
import static javaslang.API.Success;
import static javaslang.API.*;
import static javaslang.Predicates.*;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.fail;

Expand Down Expand Up @@ -1037,6 +1037,38 @@ public void shouldChainFailureWithMap() {
.map(x -> x / 2);
assertThat(actual.toString()).isEqualTo("Failure(java.lang.NumberFormatException: For input string: \"aaa\")");
}

// -- mapFailure

@SuppressWarnings("unchecked")
@Test
public void shouldMapFailureWhenSuccess() {
final Try<Integer> testee = Success(1);
final Try<Integer> actual = testee.mapFailure(
Case(instanceOf(RuntimeException.class), (Function<RuntimeException, Error>) Error::new)
);
assertThat(actual).isSameAs(testee);
}

@SuppressWarnings("unchecked")
@Test
public void shouldMapFailureWhenFailureAndMatches() {
final Try<Integer> testee = Failure(new IOException());
final Try<Integer> actual = testee.mapFailure(
Case(instanceOf(IOException.class), (Function<IOException, Error>) Error::new)
);
assertThat(actual.getCause()).isInstanceOf(Error.class);
}

@SuppressWarnings("unchecked")
@Test
public void shouldMapFailureWhenFailureButDoesNotMatch() {
final Try<Integer> testee = Failure(new IOException());
final Try<Integer> actual = testee.mapFailure(
Case(instanceOf(RuntimeException.class), (Function<RuntimeException, Error>) Error::new)
);
assertThat(actual).isSameAs(testee);
}

// -- andThen

Expand Down

0 comments on commit 237a3db

Please sign in to comment.