Reputation: 11984
I couldn't find a good solution: In my Spring Boot app, as an @ExceptionHandler
method, I need to define a handler not for a specific exception, but for any exception caused by a specific exception (i.e. a wrapped exception).
Example: Sometimes I get this:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:541) ~[spring-orm-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746) ~[spring-tx-5.1.4.RELEASE.jar:5.1.4.RELEASE]
... 121 common frames omitted
Caused by: custom.TechRoleException: My custom TechRoleException
at myapp.method1[..]
at myapp.methodOuter[..]
My custom TechRoleException
is an exception I throw inside some Hibernate EventListener's pre-update method, and the direct exception is that Persistence couldn't occur.
However, the following method that tries to use my custom exception is never reached:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(TechRoleException.class)
public String techRoleException(HttpServletRequest request, Exception ex) {
System.out.println("Got here");
return "home";
}
}
Here's a similar thread where the answer is wrong and didn't answer this question: @ExceptionHandler for Wrapped Exception / getCause() in Spring
Upvotes: 2
Views: 3507
Reputation: 11984
My final working answer is to handle a General Exception, and then use Apache ExceptionUtils.getRootCause()
to detect the specific Caused-By I'm looking for within this general handler.
(Other specific Exceptions won't come to this method if they have their dedicated Handlers. But if there's no dedicated Handler, the exception will come here.) This is the only way to detect some target Caused-By.
@ExceptionHandler(Exception.class)
public String handleGeneralException(HttpServletRequest request, Exception ex) {
Throwable rootCause = ExceptionUtils.getRootCause(ex);
if (rootCause != null && "com.myapp.TechRoleException".equals(rootCause.getClass().getName())
{
//... handle this Caused-By Exception here
// ...
}
// All other exceptions that don't have dedicated handlers can also be handled below...
// ...
}
Upvotes: 1
Reputation: 298
Maybe something like that?
@ExceptionHandler(Exception.class)
public String techRoleException(HttpServletRequest request, Exception ex) {
if(ex instanceof TechRoleException) {
System.out.println("Got here");
return "home";
} else {
throw ex; //or something else
}
}
Upvotes: 1