
io.github.oliviercailloux.jaris.exceptions.TryCatchAll Maven / Gradle / Ivy
package io.github.oliviercailloux.jaris.exceptions;
/**
* Represents either a result or a failure and provides operations to deal with cases of successes
* and of failures in a unified way.
*
* An instance of this class contains either a (non-{@code null}) result, in which case it is called
* a “success”; or a cause of type {@code X} (some {@link Exception}), in which case it is called a
* “failure”.
*
*
* Instances of this type are immutable.
*
*
* This type provides transformation operations that admit functional operators that can throw
* throwables. Some of these methods will catch all throwables thrown by such functional operators,
* while others will propagate any exception thrown to the caller (see the method documentation).
* This is the only difference between this type and the {@link Try} type: the latter catches only
* checked exceptions instead of all throwables.
*
*
* It is generally a bad idea to catch throwables that are not exceptions. Unless dealing with a
* very specific use case (such as checking correctness of some code), please consider using
* {@code Try} instead of {@code TryCatchAll}.
*
*
* When the documentation of a method indicates that it catches checked exceptions thrown by some
* provided functional interface, it is implicit that if the provided functional interface throws
* anything that is not a checked exception, then it is not caught, and simply thrown back to the
* caller.
*
*
* @param the type of result possibly kept in the instance.
*/
public interface TryCatchAll
extends TryOptionalImpl.TryVariableCatchInterface {
/**
* Returns a success containing the given result.
*
* @param the type of result declared to be (and effectively) kept in the instance
* @param result the result to contain
* @return a success
*/
public static TryCatchAll success(T result) {
return TryOptionalImpl.TryCatchAllSuccess.given(result);
}
/**
* Returns a failure containing the given cause.
*
* @param the type of result declared to be (but not effectively) kept in the instance
* @param cause the cause to contain
* @return a failure
*/
public static TryCatchAll failure(Throwable cause) {
return TryOptionalImpl.TryCatchAllFailure.given(cause);
}
/**
* Attempts to get and encapsulate a result from the given supplier.
*
* This method returns a failure iff the given supplier throws or returns {@code null}.
*
* @param the type of result declared to be kept in the instance
* @param supplier the supplier to get a result from
* @return a success containing the result if the supplier returns a result; a failure containing
* the throwable if the supplier throws
*/
public static TryCatchAll get(Throwing.Supplier extends T, ?> supplier) {
try {
return success(supplier.get());
} catch (Throwable e) {
return failure(e);
}
}
/**
* Returns a failure containing this cause if this instance is a failure, a failure containing the
* checked exception that the provided runnable threw if it did throw one, and a success containg
* the result contained in this instance if this instance is a success and the provided runnable
* does not throw.
*
* If this instance is a failure, returns this instance without running the provided runnable.
* Otherwise, if the runnable succeeds (that is, does not throw), returns this instance.
* Otherwise, if the runnable throws a checked exception, returns a failure containing the cause
* it threw.
*
* @param runnable the function to run if this instance is a success
* @return a success iff this instance is a success and the provided runnable terminated without
* throwing
*/
@Override
public abstract TryCatchAll andRun(Throwing.Runnable> runnable);
/**
* Returns a failure containing this cause if this instance is a failure, a failure containing the
* checked exception that the provided consumer threw if it did throw one, and a success containg
* the result contained in this instance otherwise.
*
* If this instance is a failure, returns this instance without running the provided consumer.
* Otherwise, if the consumer succeeds (that is, does not throw), returns this instance.
* Otherwise, if the consumer throws a checked exception, returns a failure containing the cause
* it threw.
*
* @param consumer the function to run if this instance is a success
* @return a success iff this instance is a success and the provided consumer terminated without
* throwing
*/
@Override
public abstract TryCatchAll andConsume(Throwing.Consumer super T, ?> consumer);
/**
* Returns this failure if this instance is a failure; the provided failure if it is a failure and
* this instance is a success; and a success containing the merge of the result contained in this
* instance and the one contained in {@code t2}, if they both are successes and {@code merger}
* does not return {@code null}.
*
* @param the type of result that the provided try is declared to contain
* @param the type of result that the returned try will be declared to contain
* @param a type of exception that the provided merger may throw
* @param t2 the try to consider if this try is a success
* @param merger the function invoked to merge the results if both this and the given try are
* successes
* @return a success if this instance and the given try are two successes
* @throws Y if the merger was applied and threw a checked exception
* @throws NullPointerException if the merger was applied and returned {@code null}
*/
public abstract TryCatchAll and(TryCatchAll t2,
Throwing.BiFunction super T, ? super U, ? extends V, Y> merger) throws Y;
/**
* Returns this failure if this instance is a failure; a failure containing the cause thrown by
* the given function if it threw a checked exception; a failure containing a
* {@link NullPointerException} as a cause if the provided mapper returned {@code null}; or a
* success containing the result of applying the provided mapper to the result contained in this
* instance if it is a success and the mapper returned a non-{@code null} result.
*
* Equivalent to {@code t.map(r -> TryCatchAll.get(() -> mapper.apply(r)), c -> t)}.
*
* @param the type of result that the returned try will be declared to contain
* @param mapper the mapper to apply to the result contained in this instance if it is a success
* @return a success iff this instance is a success and the provided mapper returns a
* non-{@code null} result
*/
@Override
public abstract TryCatchAll
andApply(Throwing.Function super T, ? extends U, ? extends Throwable> mapper);
/**
* Returns this instance if it is a success, or merges this instance with the one provided by the
* supplier.
*
* Returns this instance if it is a success. Otherwise, attempts to get a result from the given
* supplier. If this succeeds, that is, if the supplier returns a non-{@code null} result, returns
* a success containing that result. Otherwise, if the supplier throws, merges both throwables
* using the given {@code exceptionMerger} and returns a failure containing that merged cause,
* provided it is not {@code null}. If the supplier returns {@code null}, it is treated as if it
* had thrown a {@link NullPointerException}: this method merges the {@link NullPointerException}
* with the cause contained in this instance using the provided {@code exceptionMerger} and
* returns a failure containing that merged cause, provided it is not {@code null}.
*
*
* @param a type of exception that the provided merger may throw
* @param supplier the supplier that is invoked if this try is a failure
* @param exceptionsMerger the function invoked to merge both exceptions if this try is a failure
* and the given supplier threw a checked exception
* @return a success if this instance is a success or the given supplier returned a result
* @throws W iff the merger was applied and threw a checked exception
*/
public abstract TryCatchAll
or(Throwing.Supplier extends T, ?> supplier, Throwing.BiFunction super Throwable,
? super Throwable, ? extends Throwable, W> exceptionsMerger) throws W;
}