Is it possible to have two AfterThrows pieces of advice be applied to the same pointcut restricted by specific Exception type where one exception is a superclass of the other with, in the case of the subclass being captured, only one advice being executed?
I want to translate runtime exceptions (both custom and standard java ones) being chucked out of a service layer, where I do some specific translation in certain cases and then have a catch-all type piece of advice to translate anything truly unexpected:
@AfterThrowing(pointcut = "execution(* com.my.company.api.*(..))", throwing = "rnfex")
public void doTranslationAction(ResourceNotFoundException rnfex) {
// throw new WebApplicationException with Status.NOT_FOUND;
}
@AfterThrowing(pointcut = "execution(* com.my.company.api.*(..))", throwing = "aex")
public void doTranslationAction(AuthorisationException aex) {
// throw new WebApplicationException with Status.NOT_AUTHORISED;
}
@AfterThrowing(pointcut = "execution(* com.my.company.api.*(..))", throwing = "throwable")
public void doTranslationAction(Throwable throwable) {
// Log something here about this unexpected exception
// throw new WebApplicationException with Status.INTERNAL_SERVER_ERROR
}
I find that in this case, if I throw an exception which is explicitly catered for then the correct method is called, a translated exception is thrown, which is then captured by the broader 'Throwable' advice, then translated again into the catch-all INTERNAL_SERVER_ERROR WAE. This isn't unexpected, but just not quite what I was looking for.
To get around this I've got a single piece of advice which captures all Throwable types and then uses 'instanceof' to decide whether this is an expected custom runtime exception that I can translate into a specific WAE or not.
If I ever see 'instanceof' I'm sure I've done something to be ashamed of, but I'm not sure if there's a better way of solving this problemette without it?
I'm also against converting my expected custom exceptions to checked exceptions and then catching Runtime exception as the catch all, which could be one solution.