Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propose Try.toEither(Throwable => L) #2724

Open
wants to merge 2 commits into
base: version/1.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/main/java/io/vavr/control/Try.java
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,21 @@ public final Either<Throwable, T> toEither() {
}
}

/**
* Converts this {@code Try} to an {@link Either}, converting the Throwable (if present)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm proposing this change for the documentation so that it is more precise in meaning, because one could legitimately use a Try value to wrap a Throwable instance as a success value.

Suggested change
* Converts this {@code Try} to an {@link Either}, converting the Throwable (if present)
* Converts this {@code Try} to an {@link Either}, converting the Throwable (in the failure case)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same impression that the wording was strange, but I kept this to stay consistent with toValidation(Throwable => U).

I would make this doc change to both of these methods then, since your point applies to both cases.

* to a left value using the passed {@link Function}
*
* @param throwableMapper A transformation from throwable to the left type of the new {@code Either}
* @return A new {@code Either}
*/
public final <L> Either<L, T> toEither(Function<? super Throwable, ? extends L> throwableMapper) {
if (isFailure()) {
return Either.left(throwableMapper.apply(getCause()));
} else {
return Either.right(get());
}
}

/**
* Converts this {@code Try} to a {@link Validation}.
*
Expand Down
9 changes: 9 additions & 0 deletions src/test/java/io/vavr/control/TryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,15 @@ public void shouldConvertFailureToEitherLeftSupplier() {
assertThat(failure().toEither(() -> "test").isLeft()).isTrue();
}

@Test
public void shouldConvertFailureToEitherLeftMapper() {
final Try<Object> failure = Try.failure(new RuntimeException("a certain value"));
final Either<Boolean, Object> either = failure.toEither(t ->
t.getMessage().equals("a certain value")
);
assertThat(either).isEqualTo(Either.left(true));
Copy link
Member

@nfekete nfekete Oct 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably replace the test code in a way that limits the number of comparisons to one, which would be the one in the assertion itself.
You could use a mapper function that extracts the message from the exception and use that as the left value to compare to in the assertion. This would make the code both shorter, and — in my opinion — easier to understand, since it would have a slightly less degree of indirection.

Suggested change
final Either<Boolean, Object> either = failure.toEither(t ->
t.getMessage().equals("a certain value")
);
assertThat(either).isEqualTo(Either.left(true));
final Either<Boolean, Object> either = failure.toEither(Throwable::getMessage);
assertThat(either).isEqualTo(Either.left("a certain value"));

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, sounds much better that way 👍 I also felt a bit weird using Throwable => Boolean as my function where many people would maybe expect that to then be Predicate<Throwable>. I can see also how the equals looks like an assertion.

Main point was just to have a clear expected value returned by the function, so the suggestion sounds great

}


// -- toValidation

Expand Down