I just solved a problem like this by writing a simple utility method, which will check the entire caused-by chain.
/**
* Recursive method to determine whether an Exception passed is, or has a cause, that is a
* subclass or implementation of the Throwable provided.
*
* @param caught The Throwable to check
* @param isOfOrCausedBy The Throwable Class to look for
* @return true if 'caught' is of type 'isOfOrCausedBy' or has a cause that this applies to.
*/
private boolean isCausedBy(Throwable caught, Class<? extends Throwable> isOfOrCausedBy) {
if (caught == null) return false;
else if (isOfOrCausedBy.isAssignableFrom(caught.getClass())) return true;
else return isCausedBy(caught.getCause(), isOfOrCausedBy);
}
When you use it, you would just create a list of if's from most specific Exception to least specific, with a fallback else-clause:
try {
// Code to be executed
} catch (Exception e) {
if (isCausedBy(e, MyException.class)) {
// Handle MyException.class
} else if (isCausedBy(e, AnotherException.class)) {
// Handle AnotherException.class
} else {
throw new IllegalStateException("Error at calling service 'service'");
}
}
Alternative/Addition per requests in comments
If you want to use a similar method to get the Exception object of the class you're looking for, you can use something like this:
private Throwable getCausedByOfType(Throwable caught, Class<? extends Throwable> isOfOrCausedBy) {
if (caught == null) return null;
else if (isOfOrCausedBy.isAssignableFrom(caught.getClass())) return caught;
else return getCausedByOfType(caught.getCause(), isOfOrCausedBy);
}
This could be used in addition to isCausedBy()
this way:
if (isCausedBy(e, MyException.class)) {
Throwable causedBy = getCausedByOfType(e, MyException.class);
System.err.println(causedBy.getMessage());
}
It can also used directly instead of isCausedBy()
, although it's probably a matter of opinion whether this is more readable.
Throwable causedBy;
if ((causedBy = getCausedByOfType(e, IllegalAccessException.class)) != null) {
System.err.println(causedBy.getMessage());
}
IOException
). This is only the case if the are a lot of exception types that are similar and thus can be grouped. – Nagari