Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
Doc: ControllerAdvice @ExceptionHandler matching for root vs cause in multi-advice scenario [SPR-16074] #20623
I have ExceptionA and ExceptionB.
ExceptionB is the cause of ExceptionA.
The order of exception handlers for both exceptions are the same.
Backported to: 4.3.13
Juergen Hoeller commented
If this is about exception handler methods on separate classes, there is indeed a precedence for earlier handlers, with any methods on those classes matching first... even if they match a cause while a later handler would match the root exception. This is arguably a feature, so we can't easily change this. Within exception handler methods on the same class, we do match the root exception first before even looking for causes.
Can you declare explicit ordering there? If not, maybe we could offer an explicit flag which would allow you to express your precedence rules?
Juergen Hoeller commented
Any reason why you couldn't declare your exception handler classes with a particular order? With
The algorithm is essentially as follows: Exception handler classes are checked in their declared order. For every such class, a given exception will be resolved against its exception handler methods, checking the root class as well as the cause. Only if an exception wasn't resolve against the current handler class at all, we'll move on to the next handler class in the chain, giving it the full root+cause matching opportunity.
So effectively, a cause match on a preceding handler class is rated higher than a root exception match on a lesser-ordered handler class. If there is no specific order, the order of handler class registration matters. Since exception handler classes may apply very different treatment to their matches, a cause match on a prioritized handler class may indeed be intentional. Separating exception handler methods onto dedicated handler classes with a particular order is a way to arrive at such an arrangement; if we treated all handler classes the same, there would be no way to express such override semantics even for cause matches.
All in all, even if this is arguably not obvious, the current behavior has its sweet spot. I'm sure there are plenty of applications relying on the current matching behavior in an ordered handler class arrangement, and I'm afraid we can't take this away from them. The best we can do is to properly document that behavior, so I'm taking the opportunity to turn this issue into a documentation task.