Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 479 Vote(s) - 3.48 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Best way to check whether a certain exception type was the cause (of a cause, etc ...) in a nested exception?

#1
I am writing some JUnit tests that verify that an exception of type `MyCustomException` is thrown. However, this exception is wrapped in other exceptions a number of times, e.g. in an InvocationTargetException, which in turn is wrapped in a RuntimeException.

What's the best way to determine whether MyCustomException somehow caused the exception that I actually catch? I would like to do something like this (see underlined):
<pre><code>
try {
doSomethingPotentiallyExceptional();
fail("Expected an exception.");
} catch (RuntimeException e) {
if (!e.</code><u>wasCausedBy</u><code>(MyCustomException.class)
fail("Expected a different kind of exception.");
}
</code></pre>

I would like to avoid calling `getCause()` a few "layers" deep, and similar ugly work-arounds. Is there a nicer way?

Apparently, Spring has [NestedRuntimeException.contains(Class)][1], which does what I want - but I'm not using Spring.

[1]:

[To see links please register here]

Reply

#2
I don't think you have any choice but to call through the layers of getCause. If you look at the source code for the Spring NestedRuntimeException that you mention that is how it is implemented.
Reply

#3
Why would you want to avoid `getCause`. You can, of course, write yourself a method to perform the task, something like:

public static boolean isCause(
Class<? extends Throwable> expected,
Throwable exc
) {
return expected.isInstance(exc) || (
exc != null && isCause(expected, exc.getCause())
);
}
Reply

#4
Well, I think there's no way to do this without calling `getCause()`. It you think it's ugly implement a **utility** class for doing this:

public class ExceptionUtils {
public static boolean wasCausedBy(Throwable e, Class<? extends Throwable>) {
// call getCause() until it returns null or finds the exception
}
}
Reply

#5
Imitation is the sincerest form of flattery. [Based on a quick inspection of the source][1], this is exactly what NestedRuntimeException does:

/**
* Check whether this exception contains an exception of the given type:
* either it is of the given class itself or it contains a nested cause
* of the given type.
* @param exType the exception type to look for
* @return whether there is a nested exception of the specified type
*/
public boolean contains(Class exType) {
if (exType == null) {
return false;
}
if (exType.isInstance(this)) {
return true;
}
Throwable cause = getCause();
if (cause == this) {
return false;
}
if (cause instanceof NestedRuntimeException) {
return ((NestedRuntimeException) cause).contains(exType);
}
else {
while (cause != null) {
if (exType.isInstance(cause)) {
return true;
}
if (cause.getCause() == cause) {
break;
}
cause = cause.getCause();
}
return false;
}
}

**CAVEAT**: The above is the code as of 4 March 2009 so, if you really want to know what Spring is doing right now, you should research the code as it exists today (whenever that is).

[1]:

[To see links please register here]

Reply

#6
You can do this using guava:

FluentIterable.from(Throwables.getCausalChain(e))
.filter(Predicates.instanceOf(ConstraintViolationException.class))
.first()
.isPresent();
Reply

#7
Based on Patrick Boos answer:
If you using Apache Commons Lang 3 you can check:

**indexOfThrowable**: Returns the (zero based) index of the first Throwable that matches the specified class (**exactly**) in the exception chain. **Subclasses of the specified class do not match**

if (ExceptionUtils.indexOfThrowable(e, clazz) != -1) {
// your code
}

or

**indexOfType**: Returns the (zero based) index of the first Throwable that matches the specified **class or subclass** in the exception chain. **Subclasses of the specified class do match**

if (ExceptionUtils.indexOfType(e, clazz) != -1) {
// your code
}


Example for multiple types with Java 8:

Class<? extends Throwable>[] classes = {...}
boolean match = Arrays.stream(classes)
.anyMatch(clazz -> ExceptionUtils.indexOfType(e, clazz) != -1);
Reply

#8
If you are using [Apache Commons Lang](

[To see links please register here]

), then you can use the following:

(1) When the cause should be exactly of the specified type

if (ExceptionUtils.indexOfThrowable(exception, ExpectedException.class) != -1) {
// exception is or has a cause of type ExpectedException.class
}
(2) When the cause should be either of the specified type or its subclass type


if (ExceptionUtils.indexOfType(exception, ExpectedException.class) != -1) {
// exception is or has a cause of type ExpectedException.class or its subclass
}
Reply

#9
If the exception of interest is definitely the "root" cause, `assertj` is an additional place to find a `getRootCause` check, although from the source today, it appears to have the possible infinite loop problem discussed in other answers.

Reply

#10
You can use `ExceptionUtils.hasCause(ex, type)` from the [Apache Commons Lang](CommercialAssignmentFailureException) library.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through