/** * True in case of failure. * * @return True in case of failure. */ public boolean isFailure() { return getCause().isPresent(); }
/** * Run the given action if and only if this is a failure. * * @param action Failure listener. * @return This try. */ public Try onFailure(Consumer<? super Throwable> action) { getCause().ifPresent(action); return this; }
/** * Propagate/throw the exception in case of failure. */ public void throwException() { getCause().ifPresent(Throwing::sneakyThrow); }
/** * Always run the given action, works like a finally clause. Exception will be null in case of success. * * @param action Finally action. * @return This try result. */ public Try onComplete(Throwing.Consumer<Throwable> action) { try { action.accept(getCause().orElse(null)); return this; } catch (Throwable x) { return Try.failure(x); } }
/** * In case of failure unwrap the exception provided by calling {@link Throwable#getCause()}. * Useful for clean/shorter stackstrace. * * Example for {@link java.lang.reflect.InvocationTargetException}: * * <pre>{@code * Try.run(() -> { * Method m = ...; * m.invoke(...); //might throw InvocationTargetException * }).unwrap(InvocationTargetException.class::isInstance) * .throwException(); * }</pre> * * @param predicate Exception filter. * @return This try for success or a new failure with exception unwrap. */ public Try unwrap(Throwing.Predicate<Throwable> predicate) { try { return getCause() .filter(predicate) .map(Throwable::getCause) .filter(Objects::nonNull) .map(x -> (Try) Try.failure(x)) .orElse(this); } catch (Throwable x) { return failure(x); } }
/** * In case of failure wrap an exception matching the given predicate to something else. * * @param predicate Exception predicate. * @param wrapper Exception mapper. * @param <X> Exception type. * @return This try for success or a new failure with exception wrapped. */ public <X extends Throwable> Try wrap(Throwing.Predicate<X> predicate, Throwing.Function<X, Throwable> wrapper) { try { return getCause() .filter(x -> predicate.test((X) x)) .map(x -> (Try) Try.failure(wrapper.apply((X) x))) .orElse(this); } catch (Throwable x) { return failure(x); } }