[LANG-1647] Add and ExceptionUtils.isChecked() and isUnchecked() #1069

This commit is contained in:
Gary Gregory 2023-07-02 15:55:12 -04:00
parent 5b60305952
commit 98ef0a4138
6 changed files with 77 additions and 91 deletions

View File

@ -208,6 +208,8 @@ The <action> type attribute can be add,update,fix,remove.
<action type="add" dev="ggregory" due-to="Gary Gregory">Add Pair.accept(FailableBiConsumer).</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add Pair.apply(FailableBiFunction).</action>
<action issue="LANG-1677" type="add" dev="ggregory" due-to="Dennis Baerten, Gary Gregory">Add ReflectionDiffBuilder.setExcludeFieldNames(...) and DiffExclude a… #838.</action>
<action issue="LANG-1647" type="add" dev="ggregory" due-to="Arturo Bernal, Dimitrios Efthymiou, Gary Gregory">Add and ExceptionUtils.isChecked() and isUnchecked() #1069</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add and use ExceptionUtils.throwUnchecked(throwable).</action>
<!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Dependabot, XenoAmess, Gary Gregory">Bump actions/cache from 2.1.4 to 3.0.10 #742, #752, #764, #833, #867, #959, #964.</action>
<action type="update" dev="ggregory" due-to="Dependabot, Gary Gregory">Bump actions/checkout from 2 to 3.1.0 #819, #825, #859, #963.</action>

View File

@ -33,6 +33,7 @@ import java.util.function.Supplier;
import java.util.stream.Stream;
import org.apache.commons.lang3.Streams.FailableStream;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.function.Failable;
import org.apache.commons.lang3.function.FailableBooleanSupplier;
@ -521,12 +522,7 @@ public class Functions {
*/
public static RuntimeException rethrow(final Throwable throwable) {
Objects.requireNonNull(throwable, "throwable");
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
ExceptionUtils.throwUnchecked(throwable);
if (throwable instanceof IOException) {
throw new UncheckedIOException((IOException) throwable);
}

View File

@ -61,8 +61,7 @@ public class ConcurrentUtils {
if (ex == null || ex.getCause() == null) {
return null;
}
throwCause(ex);
ExceptionUtils.throwUnchecked(ex.getCause());
return new ConcurrentException(ex.getMessage(), ex.getCause());
}
@ -84,7 +83,7 @@ public class ConcurrentUtils {
return null;
}
throwCause(ex);
ExceptionUtils.throwUnchecked(ex.getCause());
return new ConcurrentRuntimeException(ex.getMessage(), ex.getCause());
}
@ -145,22 +144,6 @@ public class ConcurrentUtils {
return ex;
}
/**
* Tests whether the cause of the specified {@link ExecutionException}
* should be thrown and does it if necessary.
*
* @param ex the exception in question
*/
private static void throwCause(final ExecutionException ex) {
if (ex.getCause() instanceof RuntimeException) {
throw (RuntimeException) ex.getCause();
}
if (ex.getCause() instanceof Error) {
throw (Error) ex.getCause();
}
}
/**
* Invokes the specified {@link ConcurrentInitializer} and returns the
* object produced by the initializer. This method just invokes the {@code

View File

@ -23,6 +23,8 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.function.Function;
import org.apache.commons.lang3.exception.ExceptionUtils;
/**
* Definition of an interface for a wrapper around a calculation that takes a single parameter and returns a result. The
* results for the calculation will be cached for future requests.
@ -143,12 +145,6 @@ public class Memoizer<I, O> implements Computable<I, O> {
* @return a RuntimeException, Error or an IllegalStateException
*/
private RuntimeException launderException(final Throwable throwable) {
if (throwable instanceof RuntimeException) {
return (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
throw new IllegalStateException("Unchecked exception", throwable);
throw new IllegalStateException("Unchecked exception", ExceptionUtils.throwUnchecked(throwable));
}
}

View File

@ -42,8 +42,6 @@ import org.apache.commons.lang3.StringUtils;
*/
public class ExceptionUtils {
private static final int NOT_FOUND = -1;
/**
* The names of methods commonly used to access a wrapped exception.
*/
@ -63,6 +61,8 @@ public class ExceptionUtils {
"getThrowable",
};
private static final int NOT_FOUND = -1;
/**
* Used when printing stack frames to denote the start of a
* wrapped exception.
@ -82,6 +82,26 @@ public class ExceptionUtils {
throw (T) throwable;
}
/**
* Performs an action for each Throwable causes of the given Throwable.
* <p>
* A throwable without cause will return a stream containing one element - the input throwable. A throwable with one cause
* will return a stream containing two elements. - the input throwable and the cause throwable. A {@code null} throwable
* will return a stream of count zero.
* </p>
*
* <p>
* This method handles recursive cause structures that might otherwise cause infinite loops. The cause chain is
* processed until the end is reached, or until the next item in the chain is already in the result set.
* </p>
* @param throwable The Throwable to traverse.
* @param consumer a non-interfering action to perform on the elements.
* @since 3.13.0
*/
public static void forEach(final Throwable throwable, final Consumer<Throwable> consumer) {
stream(throwable).forEach(consumer);
}
/**
* Introspects the {@link Throwable} to obtain the cause.
*
@ -434,26 +454,6 @@ public class ExceptionUtils {
return list;
}
/**
* Performs an action for each Throwable causes of the given Throwable.
* <p>
* A throwable without cause will return a stream containing one element - the input throwable. A throwable with one cause
* will return a stream containing two elements. - the input throwable and the cause throwable. A {@code null} throwable
* will return a stream of count zero.
* </p>
*
* <p>
* This method handles recursive cause structures that might otherwise cause infinite loops. The cause chain is
* processed until the end is reached, or until the next item in the chain is already in the result set.
* </p>
* @param throwable The Throwable to traverse.
* @param consumer a non-interfering action to perform on the elements.
* @since 3.13.0
*/
public static void forEach(final Throwable throwable, final Consumer<Throwable> consumer) {
stream(throwable).forEach(consumer);
}
/**
* Gets the list of {@link Throwable} objects in the
* exception chain.
@ -620,6 +620,30 @@ public class ExceptionUtils {
return indexOf(throwable, type, fromIndex, true);
}
/**
* Checks if a throwable represents a checked exception
*
* @param throwable
* The throwable to check.
* @return True if the given Throwable is a checked exception.
* @since 3.13.0
*/
public static boolean isChecked(final Throwable throwable) {
return throwable != null && !(throwable instanceof Error) && !(throwable instanceof RuntimeException);
}
/**
* Checks if a throwable represents an unchecked exception
*
* @param throwable
* The throwable to check.
* @return True if the given Throwable is an unchecked exception.
* @since 3.13.0
*/
public static boolean isUnchecked(final Throwable throwable) {
return !isChecked(throwable);
}
/**
* Prints a compact stack trace for the root cause of a throwable
* to {@code System.err}.
@ -940,6 +964,25 @@ public class ExceptionUtils {
return throwableOf(throwable, type, fromIndex, true);
}
/**
* Tests whether the cause of the specified {@link Throwable}
* should be thrown and does it if necessary.
*
* @param <T> The Throwable type.
* @param throwable the throwable to test and throw or return.
* @return the given throwable.
* @since 3.13.0
*/
public static <T> T throwUnchecked(final T throwable) {
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
return throwable;
}
/**
* Throws a checked exception without adding the exception to the throws
* clause of the calling method. For checked exceptions, this method throws
@ -963,37 +1006,7 @@ public class ExceptionUtils {
* @see #hasCause(Throwable, Class)
*/
public static <R> R wrapAndThrow(final Throwable throwable) {
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
throw new UndeclaredThrowableException(throwable);
}
/**
* Checks if a throwable represents a checked exception
*
* @param throwable
* The throwable to check.
* @return True if the given Throwable is a checked exception.
* @since 3.13.0
*/
public static boolean isChecked(final Throwable throwable) {
return throwable != null && !(throwable instanceof Error) && !(throwable instanceof RuntimeException);
}
/**
* Checks if a throwable represents an unchecked exception
*
* @param throwable
* The throwable to check.
* @return True if the given Throwable is an unchecked exception.
* @since 3.13.0
*/
public static boolean isUnchecked(final Throwable throwable) {
return !isChecked(throwable);
throw new UndeclaredThrowableException(throwUnchecked(throwable));
}
/**

View File

@ -32,6 +32,7 @@ import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.stream.Streams;
import org.apache.commons.lang3.stream.Streams.FailableStream;
@ -407,12 +408,7 @@ public class Failable {
*/
public static RuntimeException rethrow(final Throwable throwable) {
Objects.requireNonNull(throwable, "throwable");
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
ExceptionUtils.throwUnchecked(throwable);
if (throwable instanceof IOException) {
throw new UncheckedIOException((IOException) throwable);
}