Option<>.collect() not to call PartialFunction on args where it is not defined #2580
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes ##2579
Expected behavior: Option<>.collect() calls PartialFunction passed as argument only for the value on which this PartialFunction is defined.
Observed behavior: PartialFunction called on values for which it is not defined, resulting in undesired behavior (i.e. unchecked exception thrown).
Example code which fails with arithmetic exception (division by zero):
Using io.vavr:vavr:0.10.2
I've checked the code and this is what I've found:
Optiona<>.collect() eventually calls PartialFunction.lift(), here
vavr/src/main/java/io/vavr/control/Option.java
Line 288 in 0b7a72c
in turn, PartialFunction.lift() looks like this:
default Function1<T, Option> lift() {
return t -> Option.when(isDefinedAt(t), apply(t));
}
— meaning
apply(t)
will be always called, no matter ifisDefinedAt(t)
returnstrue
orfalse
.vavr/src/main/java/io/vavr/PartialFunction.java
Line 126 in 0b7a72c
The proposed fix: changing the code to