diff options
| author | Ben Culkin <scorpress@gmail.com> | 2020-11-21 11:09:20 -0500 |
|---|---|---|
| committer | Ben Culkin <scorpress@gmail.com> | 2020-11-21 11:09:20 -0500 |
| commit | 023cc940331caffe6710691f16fcca92e6ad5bfa (patch) | |
| tree | ed6999808c747096c1473eefc56e952bd794913b | |
| parent | e3810fbf9b7d207e13b93f4d8698454abe78683f (diff) | |
Add a functional interface for functions that throw an exception.
This allows you to be able to throw one type of checked exception from a
normal function
It also has some methods to allow you to attempt to recover from an
exception and hide the fact that it was thrown
| -rw-r--r-- | src/main/java/bjc/functypes/ThrowFunction.java | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/main/java/bjc/functypes/ThrowFunction.java b/src/main/java/bjc/functypes/ThrowFunction.java new file mode 100644 index 0000000..b72d735 --- /dev/null +++ b/src/main/java/bjc/functypes/ThrowFunction.java @@ -0,0 +1,88 @@ +package bjc.functypes; + +import java.util.function.*; + +/** + * An instance of {@link Function} that can throw an exception. + * + * @author Ben Culkin + * + * @param <InputType> The input to the function. + * @param <ReturnType> The output to the function. + * @param <ExType> The type of exception thrown. + */ +public interface ThrowFunction<InputType, ReturnType, ExType extends Throwable> { + /** + * Does the possibly throwing computation embodied by this function. + * + * @param arg The input to the function. + * + * @return The result of the function. + * + * @throws ExType If something went wrong with the function. + */ + public ReturnType apply(InputType arg) throws ExType; + + /** + * Converts this into a {@link Function} by handling any thrown exceptions. + * + * @param clasz The class of the handled exception. This needs to be provided + * because you can't catch a generic exception, and we want to + * make sure that we aren't catching any types of exception that + * we aren't supposed to. + * + * @param handler The handler to use. + * + * @return A function which will either return its proper value, or the result + * of invoking the handler. + */ + @SuppressWarnings("unchecked") + default Function<InputType, ReturnType> swallow( + Class<ExType> clasz, Function<ExType, ReturnType> handler) { + return (inp) -> { + try { + return this.apply(inp); + } catch (Throwable ex) { + if (clasz.isInstance(ex)) { + // Swallow this + return handler.apply((ExType) ex); + } else { + String msg = "Exception of incorrect type to be handled, only " + + clasz.getName() + + " are handled"; + + throw new RuntimeException(msg, ex); + } + } + }; + } + + /** + * Convert this to a function which will attempt to recover from the thrown exception. + * + * @param clasz The class of the exception. Needed for type-safety reasons. + * @param rescue The function to use to convert an exception into a safe input value. + * + * @return A function which attempts to recover from a exception. + */ + @SuppressWarnings("unchecked") + default Function<InputType, ReturnType> recover( + Class<ExType> clasz, BiFunction<InputType, ExType, InputType> rescue) { + return Fixpoints.fix((arg, self) -> { + try { + return this.apply(arg); + } catch (Throwable ex) { + if (clasz.isInstance(ex)) { + // Swallow this + return self.apply(rescue.apply(arg, (ExType) ex)); + } else { + String msg = "Exception of incorrect type to be handled, only " + + clasz.getName() + + " are handled"; + + throw new RuntimeException(msg, ex); + } + } + }); + } +} |
