-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Description
Timothy Tong opened SPR-13726 and commented
Occasionally in the process of resolving an exception, we may raise another exception. This new exception may be caused by a variety of reasons -- the resolution itself failed, the root cause was something entirely different, etc.
If we were to throw a new exception from an @ExceptionHandler
method, the new exception would be swallowed immediately in ExceptionHandlerExceptionResolver
and we can no longer service the new exception.
We're able to service newly thrown exceptions by implementing our own DispatcherServlet and surrounding the super.processHandlerException()
with a try-catch.
However, it would be a useful if we could chain ExceptionHandlers whenever one decides to throw an exception. Example: The exception handler for ExceptionOne causes an error and throws an ExceptionTwo in the process. When this ExceptionTwo gets thrown, it will be caught by the second exception handler.
Example:
@ExceptionHandler(ExceptionOne.class)
public ModelAndView handleExceptionOne() {
if(somethingVeryBadHappens) {
// Throw this exception and let the following handler service it.
throw new ExceptionTwo(...);
}
}
@ExceptionHandler(ExceptionTwo.class)
public ModelAndView handleExceptionTwo() {
}
Here's a simple recursive example of chaining it within ExceptionHandlerExceptionResolver
. It most likely doesn't cover all cases, but it does allow the handlers to be chained.
protected ModelAndView doResolveHandlerMethodException(...) {
try {
if (logger.isDebugEnabled()) {
logger.debug("Invoking @ExceptionHandler method: " + exceptionHandlerMethod);
}
exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception);
}
catch (Exception invocationEx) {
return doResolveHandlerMethodException(request, response, handlerMethod, invocationEx);
}
}
No further details from SPR-13726