I have multiple @ControllerAdvice classes configured in my project.
One has a configuration limited to a specific package:
@ControllerAdvice("xyz.configuration")
public class ExceptionMapper
A second one has a more broad configuration:
@ControllerAdvice
public class GlobalExceptionHandler
With this setup, the ExceptionHandlerExceptionResolver picks the GlobalExceptionHandler over the ExceptionMapper.
My expectation was for the more narrowly configured class to be picked before the broader one.
Do you share this view, or do you think using @Order is the correct approach here?
Comment From: bclozel
It depends on the exception handler methods signature and other aspects.
Maybe you can share a minimal sample application to demonstrate the problem?
Comment From: kgonia
Here is sample app: https://github.com/kgonia/ControllerAdviceExample
It depends on the exception handler methods signature and other aspects.
And also based on name of beans. In the app is
AExceptionHandler and ExceptionHandler
AExceptionHandler is configured to handle all exceptions ExceptionHandler is configured to handle specific package and specific exception
If you call http://localhost:8081/test/endpoint AExceptionHandler will fire If you rename AExceptionHandler to GlobalExceptionHandle then ExceptionHandler will fire
ExceptionHandlerExceptionResolver in initExceptionHandlerAdviceCache puts all adviceBeans in exceptionHandlerAdviceCache map.
Later when exception is thrown getExceptionHandlerMethod picks ControllerAdviceBean. It checks all adviceBeans in for loop, when AExceptionHandler is first isApplicableToBeanType method returns true because it has no selectors
private boolean hasSelectors() {
return (!this.basePackages.isEmpty() || !this.assignableTypes.isEmpty() || !this.annotations.isEmpty());
}
If AExceptionHandler is renamed to GlobalExceptionHandler then ExceptionHandler is first on exceptionHandlerAdviceCache map and it's picked.
Comment From: SuganthiThomas
To ensure ExceptionHandlerExceptionResolver prioritizes a specific ControllerAdvice for a narrower set of exceptions, particularly those within a defined package, you can leverage the @Order annotation and the assignableTypes or basePackages attributes of @ControllerAdvice.
You can assign any integer value to @Order
@Order(1) has a higher priority than @Order(2). @Order(-10) has a higher priority than @Order(1)