Skip to content

Commit ea00c7c

Browse files
committed
Explicit notes on ExceptionHandler root vs cause resolution
Issue: SPR-16074
1 parent ba74e42 commit ea00c7c

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerAdvice.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.springframework.core.annotation.AliasFor;
2727
import org.springframework.stereotype.Component;
2828

29-
3029
/**
3130
* Specialization of {@link Component @Component} for classes that declare
3231
* {@link ExceptionHandler @ExceptionHandler}, {@link InitBinder @InitBinder}, or
@@ -39,10 +38,17 @@
3938
* AnnotationAwareOrderComparator}, i.e. based on
4039
* {@link org.springframework.core.annotation.Order @Order} and
4140
* {@link org.springframework.core.Ordered Ordered}, and applied in that order
42-
* at runtime. For handling exceptions the first {@code @ExceptionHandler} to
43-
* match the exception is used. For model attributes and {@code InitBinder}
44-
* initialization, {@code @ModelAttribute} and {@code @InitBinder} methods will
45-
* also follow {@code @ControllerAdvice} order.
41+
* at runtime. For handling exceptions, an {@code @ExceptionHandler} will be
42+
* picked on the first advice with a matching exception handler method. For
43+
* model attributes and {@code InitBinder} initialization, {@code @ModelAttribute}
44+
* and {@code @InitBinder} methods will also follow {@code @ControllerAdvice} order.
45+
*
46+
* <p>Note: For {@code @ExceptionHandler} methods, a root exception match will be
47+
* preferred to just matching a cause of the current exception, among the handler
48+
* methods of a particular advice bean. However, a cause match on a higher-priority
49+
* advice will still be preferred to a any match (whether root or cause level)
50+
* on a lower-priority advice bean. As a consequence, please declare your primary
51+
* root exception mappings on a prioritized advice bean with a corresponding order!
4652
*
4753
* <p>By default the methods in an {@code @ControllerAdvice} apply globally to
4854
* all Controllers. Use selectors {@link #annotations()},

src/docs/asciidoc/web/webmvc.adoc

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ If an application context hierarchy is not required, applications may configure
209209

210210

211211

212-
213212
[[mvc-servlet-special-bean-types]]
214213
=== Special Bean Types
215214
[.small]#<<web-reactive.adoc#webflux-special-bean-types,Same in Spring WebFlux>>#
@@ -575,7 +574,7 @@ view technologies.
575574
==== Redirect
576575

577576
The special `redirect:` prefix in a view name allows you to perform a redirect. The
578-
`UrlBasedViewResolver` (and sub-classes) will recognize this as a special indication that a
577+
`UrlBasedViewResolver` (and subclasses) will recognize this as a special indication that a
579578
redirect is needed. The rest of the view name will be treated as the redirect URL.
580579

581580
The net effect is the same as if the controller had returned a `RedirectView`, but now
@@ -592,7 +591,7 @@ value takes precedence over the response status set by `RedirectView`.
592591
==== Forward
593592

594593
It is also possible to use a special `forward:` prefix for view names that are
595-
ultimately resolved by `UrlBasedViewResolver` and sub-classes. This creates an
594+
ultimately resolved by `UrlBasedViewResolver` and subclasses. This creates an
596595
`InternalResourceView` which does a `RequestDispatcher.forward()`.
597596
Therefore, this prefix is not useful with `InternalResourceViewResolver` and
598597
`InternalResourceView` (for JSPs) but it can be helpful if using another view
@@ -1351,7 +1350,6 @@ default it is set to `true`.
13511350

13521351
[TIP]
13531352
====
1354-
13551353
The MVC Java config and the MVC namespace both provide options for enabling the use of
13561354
matrix variables.
13571355
@@ -2593,7 +2591,6 @@ for more details.
25932591

25942592
[TIP]
25952593
====
2596-
25972594
What happens when a model attribute name is not explicitly specified? In such cases a
25982595
default name is assigned to the model attribute based on its type. For example if the
25992596
method returns an object of type `Account`, the default name used is "account". You can
@@ -2739,7 +2736,7 @@ You can also expand and encode using individual URI components:
27392736
.encode();
27402737
----
27412738

2742-
In a Servlet environment the `ServletUriComponentsBuilder` sub-class provides static
2739+
In a Servlet environment the `ServletUriComponentsBuilder` subclass provides static
27432740
factory methods to copy available URL information from a Servlet requests:
27442741

27452742
[source,java,indent=0]
@@ -2962,7 +2959,7 @@ error content to the body of the response.
29622959

29632960
You can do that with `@ExceptionHandler` methods. When declared within a controller such
29642961
methods apply to exceptions raised by `@RequestMapping` methods of that controller (or
2965-
any of its sub-classes). You can also declare an `@ExceptionHandler` method within an
2962+
any of its subclasses). You can also declare an `@ExceptionHandler` method within an
29662963
`@ControllerAdvice` class in which case it handles exceptions from `@RequestMapping`
29672964
methods from many controllers. Below is an example of a controller-local
29682965
`@ExceptionHandler` method:
@@ -2989,6 +2986,16 @@ is thrown that matches one of the types in the list, then the method annotated w
29892986
matching `@ExceptionHandler` will be invoked. If the annotation value is not set then
29902987
the exception types listed as method arguments are used.
29912988

2989+
[TIP]
2990+
====
2991+
For `@ExceptionHandler` methods, a root exception match will be preferred to just
2992+
matching a cause of the current exception, among the handler methods of a particular
2993+
controller or advice bean. However, a cause match on a higher-priority `@ControllerAdvice`
2994+
will still be preferred to a any match (whether root or cause level) on a lower-priority
2995+
advice bean. As a consequence, when using a multi-advice arrangement, please declare your
2996+
primary root exception mappings on a prioritized advice bean with a corresponding order!
2997+
====
2998+
29922999
Much like standard controller methods annotated with a `@RequestMapping` annotation, the
29933000
method arguments and return values of `@ExceptionHandler` methods can be flexible. For
29943001
example, the `HttpServletRequest` can be accessed in Servlet environments. The return
@@ -3341,7 +3348,7 @@ the response.
33413348
[[mvc-ann-async-sse]]
33423349
=== Server-Sent Events
33433350

3344-
`SseEmitter` is a sub-class of `ResponseBodyEmitter` providing support for
3351+
`SseEmitter` is a subclass of `ResponseBodyEmitter` providing support for
33453352
http://www.w3.org/TR/eventsource/[Server-Sent Events].
33463353
Server-sent events is a just another variation on the same "HTTP Streaming"
33473354
technique except events pushed from the server are formatted according to
@@ -3696,12 +3703,10 @@ then resolved into the `/WEB-INF/jsp/registration.jsp` view by the
36963703

36973704
[TIP]
36983705
====
3699-
37003706
You do not need to define a `DefaultRequestToViewNameTranslator` bean explicitly. If you
37013707
like the default settings of the `DefaultRequestToViewNameTranslator`, you can rely on
37023708
the Spring Web MVC `DispatcherServlet` to instantiate an instance of this class if one
37033709
is not explicitly configured.
3704-
37053710
====
37063711

37073712
Of course, if you need to change the default settings, then you do need to configure

0 commit comments

Comments
 (0)