|
|
|
@ -3492,28 +3492,35 @@ include::webflux-cors.adoc[leveloffset=+1]
@@ -3492,28 +3492,35 @@ include::webflux-cors.adoc[leveloffset=+1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[webflux-ann-rest-exceptions]] |
|
|
|
|
== REST API exceptions |
|
|
|
|
[.small]#<<web.adoc#mvc-ann-rest-exceptions, Web MVC>># |
|
|
|
|
== Error Responses |
|
|
|
|
[.small]#<<webmvc.adoc#mvc-ann-rest-exceptions, Web MVC>># |
|
|
|
|
|
|
|
|
|
A common requirement for REST services is to include details in the body of an error |
|
|
|
|
response. The Spring Framework supports the "Problem Details for HTTP APIs" |
|
|
|
|
specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807]. These are the main |
|
|
|
|
abstractions for this support: |
|
|
|
|
A common requirement for REST services is to include details in the body of error |
|
|
|
|
responses. The Spring Framework supports the "Problem Details for HTTP APIs" |
|
|
|
|
specification, https://www.rfc-editor.org/rfc/rfc7807.html[RFC 7807]. |
|
|
|
|
|
|
|
|
|
The following are the main abstractions for this support: |
|
|
|
|
|
|
|
|
|
- `ProblemDetail` -- representation for an RFC 7807 problem detail; a simple container |
|
|
|
|
for both standard fields defined in the spec, and for non-standard ones. |
|
|
|
|
- `ErrorResponse` -- contract to expose HTTP error response details including HTTP |
|
|
|
|
status, response headers, and a body in the format of RFC 7807; this allows exceptions to |
|
|
|
|
encapsulate and expose the details of how they map to an HTTP response. All Spring MVC |
|
|
|
|
encapsulate and expose the details of how they map to an HTTP response. All Spring WebFlux |
|
|
|
|
exceptions implement this. |
|
|
|
|
- `ErrorResponseException` -- basic `ErrorResponse` implementation that others |
|
|
|
|
can use as a convenient base class. |
|
|
|
|
- `ResponseEntityExceptionHandler` -- convenient base class for an |
|
|
|
|
<<webflux-ann-controller-advice,@ControllerAdvice>> that handles all Spring MVC exceptions, |
|
|
|
|
<<webflux-ann-controller-advice,@ControllerAdvice>> that handles all Spring WebFlux exceptions, |
|
|
|
|
and any `ErrorResponseException`, and renders an error response with a body. |
|
|
|
|
|
|
|
|
|
You can return `ProblemDetail` or `ErrorResponse` directly from `@RequestMapping` or |
|
|
|
|
from `@ExceptionHandler` controller methods to render an RFC 7807 response as follows: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[webflux-ann-rest-exceptions-render]] |
|
|
|
|
=== Render |
|
|
|
|
[.small]#<<webmvc.adoc#mvc-ann-rest-exceptions-render, Web MVC>># |
|
|
|
|
|
|
|
|
|
You can return `ProblemDetail` or `ErrorResponse` from any `@ExceptionHandler` or from |
|
|
|
|
any `@RequestMapping` method to render an RFC 7807 response as follows: |
|
|
|
|
|
|
|
|
|
- The `status` property of `ProblemDetail` determines the HTTP status. |
|
|
|
|
- The `instance` property of `ProblemDetail` is set from the current URL path, if not |
|
|
|
@ -3522,20 +3529,106 @@ already set.
@@ -3522,20 +3529,106 @@ already set.
|
|
|
|
|
"application/problem+json" over "application/json" when rendering a `ProblemDetail`, |
|
|
|
|
and also falls back on it if no compatible media type is found. |
|
|
|
|
|
|
|
|
|
You can extend an RFC 7807 response with non-standard fields as follows: |
|
|
|
|
To enable RFC 7807 responses for Spring WebFlux exceptions and for any |
|
|
|
|
`ErrorResponseException`, extend `ResponseEntityExceptionHandler` and declare it as an |
|
|
|
|
<<webflux-ann-controller-advice,@ControllerAdvice>> in Spring configuration. The handler |
|
|
|
|
obtains HTTP status, headers, and error details from each exception and prepares a |
|
|
|
|
`ResponseEntity`. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[webflux-ann-rest-exceptions-non-standard]] |
|
|
|
|
=== Non-Standard Fields |
|
|
|
|
[.small]#<<webmvc.adoc#mvc-ann-rest-exceptions-non-standard, Web MVC>># |
|
|
|
|
|
|
|
|
|
You can extend an RFC 7807 response with non-standard fields in one of two ways. |
|
|
|
|
|
|
|
|
|
- Insert into the "properties" `Map` of `ProblemDetail`. When using the Jackson |
|
|
|
|
One, insert into the "properties" `Map` of `ProblemDetail`. When using the Jackson |
|
|
|
|
library, the Spring Framework registers `ProblemDetailJacksonMixin` that ensures this |
|
|
|
|
"properties" `Map` is unwrapped and rendered as top level JSON properties in the |
|
|
|
|
response, and likewise any unknown property during deserialization is inserted into |
|
|
|
|
this `Map`. |
|
|
|
|
- Extend `ProblemDetail` to add dedicated non-standard properties. The copy constructor |
|
|
|
|
in `ProblemDetail` allows a sub-class to make it easy to be created from an existing |
|
|
|
|
`ProblemDetail`. This could be done centrally, e.g. from an `@ControllerAdvice` such as |
|
|
|
|
`ResponseEntityExceptionHandler` that re-creates the `ProblemDetail` of an exception into |
|
|
|
|
a subclass with the additional non-standard fields. |
|
|
|
|
|
|
|
|
|
A client application can catch `WebClientResponseException` and use its |
|
|
|
|
You can also extend `ProblemDetail` to add dedicated non-standard properties. |
|
|
|
|
The copy constructor in `ProblemDetail` allows a sub-class to make it easy to be created |
|
|
|
|
from an existing `ProblemDetail`. This could be done centrally, e.g. from an |
|
|
|
|
`@ControllerAdvice` such as `ResponseEntityExceptionHandler` that re-creates the |
|
|
|
|
`ProblemDetail` of an exception into a subclass with the additional non-standard fields. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[webflux-ann-rest-exceptions-i8n]] |
|
|
|
|
=== Internationalization |
|
|
|
|
[.small]#<<webmvc.adoc#mvc-ann-rest-exceptions-i8n, Web MVC>># |
|
|
|
|
|
|
|
|
|
It is a common requirement to internationalize error response details, and good practice |
|
|
|
|
to customize the problem details for Spring WebFlux exceptions. This is supported as follows: |
|
|
|
|
|
|
|
|
|
- Each `ErrorResponse` exposes a message code and message code arguments to resolve the |
|
|
|
|
problem "detail" field through a <<core.adoc#context-functionality-messagesource,MessageSource>>. |
|
|
|
|
The actual message code value is parameterized with placeholders, e.g. |
|
|
|
|
`"HTTP method {0} not supported"` to be expanded from the arguments. |
|
|
|
|
- `ResponseEntityExceptionHandler` uses the message code and the message arguments |
|
|
|
|
to resolve the problem "detail" field. |
|
|
|
|
|
|
|
|
|
Message codes default to "problemDetail." + the fully qualified exception class name. Some |
|
|
|
|
exceptions may expose additional message codes in which case a suffix is added to |
|
|
|
|
the default message code. The table below lists message arguments and codes for Spring |
|
|
|
|
WebFlux exceptions: |
|
|
|
|
|
|
|
|
|
[[webflux-ann-rest-exceptions-codes]] |
|
|
|
|
[cols="1,1,2", options="header"] |
|
|
|
|
|=== |
|
|
|
|
| Exception | Message Code | Message Code Arguments |
|
|
|
|
|
|
|
|
|
| `UnsupportedMediaTypeStatusException` |
|
|
|
|
| (default) |
|
|
|
|
| `{0}` the media type that is not supported, `{1}` list of supported media types |
|
|
|
|
|
|
|
|
|
| `UnsupportedMediaTypeStatusException` |
|
|
|
|
| (default) + ".parseError" |
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
| `MissingRequestValueException` |
|
|
|
|
| (default) |
|
|
|
|
| `{0}` a label for the value (e.g. "request header", "cookie value", ...), `{1}` the value name |
|
|
|
|
|
|
|
|
|
| `UnsatisfiedRequestParameterException` |
|
|
|
|
| (default) |
|
|
|
|
| `{0}` the list of parameter conditions |
|
|
|
|
|
|
|
|
|
| `WebExchangeBindException` |
|
|
|
|
| (default) |
|
|
|
|
| `{0}` the list of global errors, `{1}` the list of field errors. |
|
|
|
|
Message codes and arguments for each error within the `BindingResult` are also resolved |
|
|
|
|
via `MessageSource`. |
|
|
|
|
|
|
|
|
|
| `NotAcceptableStatusException` |
|
|
|
|
| (default) |
|
|
|
|
| `{0}` list of supported media types |
|
|
|
|
|
|
|
|
|
| `NotAcceptableStatusException` |
|
|
|
|
| (default) + ".parseError" |
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
| `ServerErrorException` |
|
|
|
|
| (default) |
|
|
|
|
| `{0}` the failure reason provided to the class constructor |
|
|
|
|
|
|
|
|
|
| `MethodNotAllowedException` |
|
|
|
|
| (default) |
|
|
|
|
| `{0}` the current HTTP method, `{1}` the list of supported HTTP methods |
|
|
|
|
|
|
|
|
|
|=== |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[[webflux-ann-rest-exceptions-client]] |
|
|
|
|
=== Client Handling |
|
|
|
|
[.small]#<<webmvc.adoc#mvc-ann-rest-exceptions-client, Web MVC>># |
|
|
|
|
|
|
|
|
|
A client application can catch `WebClientResponseException`, when using the `WebClient`, |
|
|
|
|
or `RestClientResponseException` when using the `RestTemplate`, and use their |
|
|
|
|
`getResponseBodyAs` methods to decode the error response body to any target type such as |
|
|
|
|
`ProblemDetail`, or a subclass of `ProblemDetail`. |
|
|
|
|
|
|
|
|
|