Skip to content

Commit

Permalink
[LANG-1647] Add and ExceptionUtils.isChecked() and isUnchecked() #1069
Browse files Browse the repository at this point in the history
  • Loading branch information
garydgregory committed Jul 2, 2023
1 parent 5b60305 commit 98ef0a4
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 91 deletions.
2 changes: 2 additions & 0 deletions src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/org/apache/commons/lang3/Functions.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
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;

Expand Down Expand Up @@ -521,12 +522,7 @@ private static <T extends Throwable> boolean getAsBoolean(final FailableBooleanS
*/
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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ public static ConcurrentException extractCause(final ExecutionException ex) {
if (ex == null || ex.getCause() == null) {
return null;
}

throwCause(ex);
ExceptionUtils.throwUnchecked(ex.getCause());
return new ConcurrentException(ex.getMessage(), ex.getCause());
}

Expand All @@ -84,7 +83,7 @@ public static ConcurrentRuntimeException extractCauseUnchecked(
return null;
}

throwCause(ex);
ExceptionUtils.throwUnchecked(ex.getCause());
return new ConcurrentRuntimeException(ex.getMessage(), ex.getCause());
}

Expand Down Expand Up @@ -145,22 +144,6 @@ static Throwable checkedException(final Throwable ex) {
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
Expand Down
10 changes: 3 additions & 7 deletions src/main/java/org/apache/commons/lang3/concurrent/Memoizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
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.
Expand Down Expand Up @@ -143,12 +145,6 @@ public O compute(final I arg) throws InterruptedException {
* @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));
}
}
119 changes: 66 additions & 53 deletions src/main/java/org/apache/commons/lang3/exception/ExceptionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
*/
public class ExceptionUtils {

private static final int NOT_FOUND = -1;

/**
* The names of methods commonly used to access a wrapped exception.
*/
Expand All @@ -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.
Expand All @@ -82,6 +82,26 @@ private static <R, T extends Throwable> R eraseType(final Throwable throwable) t
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.
*
Expand Down Expand Up @@ -434,26 +454,6 @@ public static List<Throwable> getThrowableList(Throwable throwable) {
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.
Expand Down Expand Up @@ -620,6 +620,30 @@ public static int indexOfType(final Throwable throwable, final Class<? extends T
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}.
Expand Down Expand Up @@ -940,6 +964,25 @@ public static <T extends Throwable> T throwableOfType(final Throwable throwable,
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
Expand All @@ -963,37 +1006,7 @@ public static <T extends Throwable> T throwableOfType(final Throwable throwable,
* @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));
}

/**
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/org/apache/commons/lang3/function/Failable.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
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;

Expand Down Expand Up @@ -407,12 +408,7 @@ public static <E extends Throwable> short getAsShort(final FailableShortSupplier
*/
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);
}
Expand Down

0 comments on commit 98ef0a4

Please sign in to comment.