Skip to content

Commit

Permalink
Add CheckedSupplier to replace CheckedException
Browse files Browse the repository at this point in the history
  • Loading branch information
2bllw8 committed Feb 21, 2022
1 parent 8fb6509 commit 7201261
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 45 deletions.
14 changes: 4 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ implementation 'io.github.2bllw8:either:3.1.0'
## Usage

```java
import exe.bbllw8.either.CheckedException;
import exe.bbllw8.either.Try;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
Expand All @@ -45,14 +43,10 @@ import java.util.stream.Collectors;
public class Main {

public static void main(String[] args) {
Arrays.stream(args).map((String arg) -> Try.from(() -> {
try {
return Files.lines(Paths.get(arg))
.collect(Collectors.joining("\n"));
} catch (IOException e) {
throw new CheckedException(e);
}
}).filter(text -> text.length() > 2)
Arrays.stream(args).map((String arg) -> Try.from(() ->
Files.lines(Paths.get(arg))
.collect(Collectors.joining("\n")))
.filter(text -> text.length() > 2)
.map(text -> text.substring(2))
.flatMap(text -> Try.from(() -> Integer.parseInt(text)))
.toEither()
Expand Down
8 changes: 4 additions & 4 deletions lib/src/main/java/exe/bbllw8/either/CheckedException.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
*/
package exe.bbllw8.either;

import java.util.function.Supplier;

/**
* A CheckedException instance is used to <i>catch</i> checked Exceptions for usage in {@link
* Try#from(Supplier)}.
* Try#from(CheckedSupplier)}.
*
* <pre>
* public class Example {
Expand All @@ -25,9 +23,11 @@
* </pre>
*
* @author 2bllw8
* @see Try#from(Supplier)
* @see Try#from(CheckedSupplier)
* @since 2.2.0
* @deprecated Use {@link CheckedSupplier} instead of thowing wrapped exceptions.
*/
@Deprecated
public final class CheckedException extends RuntimeException {

private static final long serialVersionUID = 2896775411630760282L;
Expand Down
18 changes: 18 additions & 0 deletions lib/src/main/java/exe/bbllw8/either/CheckedSupplier.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2022 2bllw8
* SPDX-License-Identifier: Apache-2.0
*/
package exe.bbllw8.either;

/**
* Represents a supplier of results that may throw a {@link Throwable}.
*
* @param <T> The type of result supplied by this supplier
* @author 2bllw8
* @since 3.2.0
*/
@FunctionalInterface
public interface CheckedSupplier<T> {

T get() throws Throwable;
}
14 changes: 14 additions & 0 deletions lib/src/main/java/exe/bbllw8/either/Failure.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public final class Failure<T> extends Try<T> {
private transient final Throwable throwable;

public Failure(Throwable throwable) {
assertNotFatal(throwable);
this.throwable = throwable;
}

Expand Down Expand Up @@ -140,4 +141,17 @@ public int hashCode() {
public String toString() {
return "Failure(" + throwable + ')';
}

/**
* Assert that the given throwable is not fatal.
*/
private static void assertNotFatal(Throwable t) {
if (t instanceof VirtualMachineError) {
throw (VirtualMachineError) t;
} else if (t instanceof ThreadDeath) {
throw (ThreadDeath) t;
} else if (t instanceof LinkageError) {
throw (LinkageError) t;
}
}
}
40 changes: 11 additions & 29 deletions lib/src/main/java/exe/bbllw8/either/Try.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
* The {@link Try} type represents a computation that may either result in an exception, or return a
Expand Down Expand Up @@ -40,7 +39,7 @@ public abstract class Try<T> {
* <ul>
* <li>{@link Success}</li>
* <li>{@link Failure}</li>
* <li>{@link Try#from(Supplier)}</li>
* <li>{@link Try#from(CheckedSupplier)}</li>
* </ul>
*
* @hidden
Expand Down Expand Up @@ -205,36 +204,19 @@ public static <T> Try<T> flatten(Try<Try<T>> tryTry) {
*
* @since 3.0.0
*/
@SuppressWarnings({"PMD.AvoidCatchingThrowable"})
public static <T> Try<T> from(Supplier<T> supplier) {
@SuppressWarnings({
"deprecation",
"PMD.AvoidCatchingThrowable",
})
public static <T> Try<T> from(CheckedSupplier<T> supplier) {
//noinspection deprecation
try {
return new Success<>(supplier.get());
} catch (CheckedException e) {
// Wrapped checked exception
final Throwable t = e.getCause();
if (isFatal(t)) {
// Fatal
throw e;
} else {
return new Failure<>(t);
}
} catch (CheckedException t) {
// TODO: remove this clause when CheckedException is removed
return new Failure<>(t.getCause());
} catch (Throwable t) {
if (isFatal(t)) {
// Fatal
throw t;
} else {
return new Failure<>(t);
}
return new Failure<>(t);
}
}

/**
* @return Returns whether the given throwable is fatal.
*/
private static boolean isFatal(Throwable t) {
return t instanceof VirtualMachineError
|| t instanceof ThreadDeath
|| t instanceof InterruptedException
|| t instanceof LinkageError;
}
}
30 changes: 30 additions & 0 deletions lib/src/test/java/exe/bbllw8/either/FailureTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,34 @@ public void stringRepresentation() {
throw new IllegalStateException("something");
}).toString());
}

@Test
public void multipleThrow() {
Assert.assertTrue("Multiple thrown classes are handled (throwable #1)",
Try.from(() -> new IntToBoolean().convert(2))
.recover(t -> t instanceof IllegalAccessException)
.get());
Assert.assertTrue("Multiple thrown classes are handled (throwable #2)",
Try.from(() -> new IntToBoolean().convert(3))
.recover(t -> t instanceof IllegalArgumentException)
.get());
}

private static class IntToBoolean {

boolean convert(int result) throws IllegalAccessException, IllegalArgumentException {
switch (result) {
case 0:
return false;
case 1:
return true;
case 2:
// You have no authority to discover the dark truth about
// the third hidden boolean value
throw new IllegalAccessException();
default:
throw new IllegalArgumentException();
}
}
}
}
2 changes: 1 addition & 1 deletion lib/src/test/java/exe/bbllw8/either/SuccessTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public void transform() {
new Success<>(12),
Try.from(() -> "12").transform(value -> Try.from(() -> Integer.parseInt(value)),
t -> Try.from(() -> {
throw new CheckedException(t);
throw t;
})));
}

Expand Down
2 changes: 1 addition & 1 deletion lib/src/test/java/exe/bbllw8/either/TryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void flatten() {
public void from() {
Assert.assertTrue("A supplier throwing an exception should return a failure",
Try.from(() -> {
throw new CheckedException(new Throwable());
throw new Throwable();
}).isFailure());
Assert.assertTrue("A supplier throwing an exception should return a failure",
Try.from(() -> Integer.parseInt("-")).isFailure());
Expand Down

0 comments on commit 7201261

Please sign in to comment.