|
For the latest stable version, please use Spring Framework 6.2.12! |
Exceptions
@Controller and @ControllerAdvice classes can have
@ExceptionHandler methods to handle exceptions from controller methods, as the following example shows:
-
Java
-
Kotlin
@Controller
public class SimpleController {
// ...
@ExceptionHandler
public ResponseEntity<String> handle(IOException ex) {
// ...
}
}
@Controller
class SimpleController {
// ...
@ExceptionHandler
fun handle(ex: IOException): ResponseEntity<String> {
// ...
}
}
The exception may match against a top-level exception being propagated (e.g. a direct
IOException being thrown) or against a nested cause within a wrapper exception (e.g.
an IOException wrapped inside an IllegalStateException). As of 5.3, this can match
at arbitrary cause levels, whereas previously only an immediate cause was considered.
For matching exception types, preferably declare the target exception as a method argument,
as the preceding example shows. When multiple exception methods match, a root exception match is
generally preferred to a cause exception match. More specifically, the ExceptionDepthComparator
is used to sort exceptions based on their depth from the thrown exception type.
Alternatively, the annotation declaration may narrow the exception types to match, as the following example shows:
-
Java
-
Kotlin
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(IOException ex) {
// ...
}
@ExceptionHandler(FileSystemException::class, RemoteException::class)
fun handle(ex: IOException): ResponseEntity<String> {
// ...
}
You can even use a list of specific exception types with a very generic argument signature, as the following example shows:
-
Java
-
Kotlin
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(Exception ex) {
// ...
}
@ExceptionHandler(FileSystemException::class, RemoteException::class)
fun handle(ex: Exception): ResponseEntity<String> {
// ...
}
|
The distinction between root and cause exception matching can be surprising. In the The behavior is even simpler in the |
We generally recommend that you be as specific as possible in the argument signature,
reducing the potential for mismatches between root and cause exception types.
Consider breaking a multi-matching method into individual @ExceptionHandler
methods, each matching a single specific exception type through its signature.
In a multi-@ControllerAdvice arrangement, we recommend declaring your primary root exception
mappings on a @ControllerAdvice prioritized with a corresponding order. While a root
exception match is preferred to a cause, this is defined among the methods of a given
controller or @ControllerAdvice class. This means a cause match on a higher-priority
@ControllerAdvice bean is preferred to any match (for example, root) on a lower-priority
@ControllerAdvice bean.
Last but not least, an @ExceptionHandler method implementation can choose to back
out of dealing with a given exception instance by rethrowing it in its original form.
This is useful in scenarios where you are interested only in root-level matches or in
matches within a specific context that cannot be statically determined. A rethrown
exception is propagated through the remaining resolution chain, as though
the given @ExceptionHandler method would not have matched in the first place.
Support for @ExceptionHandler methods in Spring MVC is built on the DispatcherServlet
level, HandlerExceptionResolver mechanism.
Method Arguments
@ExceptionHandler methods support the following arguments:
| Method argument | Description |
|---|---|
Exception type |
For access to the raised exception. |
|
For access to the controller method that raised the exception. |
|
Generic access to request parameters and request and session attributes without direct use of the Servlet API. |
|
Choose any specific request or response type (for example, |
|
Enforces the presence of a session. As a consequence, such an argument is never |
|
Currently authenticated user — possibly a specific |
|
The HTTP method of the request. |
|
The current request locale, determined by the most specific |
|
The time zone associated with the current request, as determined by a |
|
For access to the raw response body, as exposed by the Servlet API. |
|
For access to the model for an error response. Always empty. |
|
Specify attributes to use in case of a redirect — (that is to be appended to the query string) and flash attributes to be stored temporarily until the request after the redirect. See Redirect Attributes and Flash Attributes. |
|
For access to any session attribute, in contrast to model attributes stored in the
session as a result of a class-level |
|
For access to request attributes. See |
Return Values
@ExceptionHandler methods support the following return values:
| Return value | Description |
|---|---|
|
The return value is converted through |
|
The return value specifies that the full response (including the HTTP headers and the body)
be converted through |
|
To render an RFC 9457 error response with details in the body, see Error Responses |
|
To render an RFC 9457 error response with details in the body, see Error Responses |
|
A view name to be resolved with |
|
A |
|
Attributes to be added to the implicit model with the view name implicitly determined
through a |
|
An attribute to be added to the model with the view name implicitly determined through
a Note that |
|
The view and model attributes to use and, optionally, a response status. |
|
A method with a If none of the above is true, a |
Any other return value |
If a return value is not matched to any of the above and is not a simple type (as determined by BeanUtils#isSimpleProperty), by default, it is treated as a model attribute to be added to the model. If it is a simple type, it remains unresolved. |