| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | [[webflux-ann-rest-exceptions]] | 
					
						
							|  |  |  | = Error Responses | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:17 +08:00
										 |  |  | [.small]#xref:web/webmvc/mvc-ann-rest-exceptions.adoc[See equivalent in the Servlet stack]# | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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" | 
					
						
							| 
									
										
										
										
											2024-05-13 16:42:35 +08:00
										 |  |  | specification, {rfc-site}/rfc9457.html[RFC 9457]. | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | The following are the main abstractions for this support: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-13 16:42:35 +08:00
										 |  |  | - `ProblemDetail` -- representation for an RFC 9457 problem detail; a simple container | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | for both standard fields defined in the spec, and for non-standard ones. | 
					
						
							|  |  |  | - `ErrorResponse` -- contract to expose HTTP error response details including HTTP | 
					
						
							| 
									
										
										
										
											2024-05-13 16:42:35 +08:00
										 |  |  | status, response headers, and a body in the format of RFC 9457; this allows exceptions to | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:17 +08:00
										 |  |  | xref:web/webflux/controller/ann-advice.adoc[@ControllerAdvice] that handles all Spring WebFlux exceptions, | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | and any `ErrorResponseException`, and renders an error response with a body. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[webflux-ann-rest-exceptions-render]] | 
					
						
							|  |  |  | == Render | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:17 +08:00
										 |  |  | [.small]#xref:web/webmvc/mvc-ann-rest-exceptions.adoc#mvc-ann-rest-exceptions-render[See equivalent in the Servlet stack]# | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | You can return `ProblemDetail` or `ErrorResponse` from any `@ExceptionHandler` or from | 
					
						
							| 
									
										
										
										
											2024-05-13 16:42:35 +08:00
										 |  |  | any `@RequestMapping` method to render an RFC 9457 response. This is processed as follows: | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | - The `status` property of `ProblemDetail` determines the HTTP status. | 
					
						
							|  |  |  | - The `instance` property of `ProblemDetail` is set from the current URL path, if not | 
					
						
							|  |  |  | already set. | 
					
						
							|  |  |  | - For content negotiation, the Jackson `HttpMessageConverter` prefers | 
					
						
							|  |  |  | "application/problem+json" over "application/json" when rendering a `ProblemDetail`, | 
					
						
							|  |  |  | and also falls back on it if no compatible media type is found. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-13 16:42:35 +08:00
										 |  |  | To enable RFC 9457 responses for Spring WebFlux exceptions and for any | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | `ErrorResponseException`, extend `ResponseEntityExceptionHandler` and declare it as an | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:17 +08:00
										 |  |  | xref:web/webflux/controller/ann-advice.adoc[@ControllerAdvice] in Spring configuration. The handler | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | has an `@ExceptionHandler` method that handles any `ErrorResponse` exception, which | 
					
						
							|  |  |  | includes all built-in web exceptions. You can add more exception handling methods, and | 
					
						
							|  |  |  | use a protected method to map any exception to a `ProblemDetail`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-28 00:53:50 +08:00
										 |  |  | You can register `ErrorResponse` interceptors through the | 
					
						
							|  |  |  | xref:web/webflux/config.adoc[WebFlux Config] with a `WebFluxConfigurer`. Use that to intercept | 
					
						
							|  |  |  | any RFC 7807 response and take some action. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[webflux-ann-rest-exceptions-non-standard]] | 
					
						
							|  |  |  | == Non-Standard Fields | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:17 +08:00
										 |  |  | [.small]#xref:web/webmvc/mvc-ann-rest-exceptions.adoc#mvc-ann-rest-exceptions-non-standard[See equivalent in the Servlet stack]# | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-13 16:42:35 +08:00
										 |  |  | You can extend an RFC 9457 response with non-standard fields in one of two ways. | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can also extend `ProblemDetail` to add dedicated non-standard properties. | 
					
						
							|  |  |  | The copy constructor in `ProblemDetail` allows a subclass 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-i18n]] | 
					
						
							| 
									
										
										
										
											2023-07-06 00:07:30 +08:00
										 |  |  | == Customization and i18n | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:17 +08:00
										 |  |  | [.small]#xref:web/webmvc/mvc-ann-rest-exceptions.adoc#mvc-ann-rest-exceptions-i18n[See equivalent in the Servlet stack]# | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-06 00:07:30 +08:00
										 |  |  | It is a common requirement to customize and internationalize error response details. | 
					
						
							|  |  |  | It is also good practice to customize the problem details for Spring WebFlux exceptions | 
					
						
							|  |  |  | to avoid revealing implementation details. This section describes the support for that. | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-06 00:07:30 +08:00
										 |  |  | An `ErrorResponse` exposes message codes for "type", "title", and "detail", as well as | 
					
						
							| 
									
										
										
										
											2023-06-14 22:57:04 +08:00
										 |  |  | message code arguments for the "detail" field. `ResponseEntityExceptionHandler` resolves | 
					
						
							|  |  |  | these through a xref:core/beans/context-introduction.adoc#context-functionality-messagesource[MessageSource] | 
					
						
							| 
									
										
										
										
											2023-07-06 00:07:30 +08:00
										 |  |  | and updates the corresponding `ProblemDetail` fields accordingly. | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 22:57:04 +08:00
										 |  |  | The default strategy for message codes follows the pattern: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `problemDetail.[type|title|detail].[fully qualified exception class name]` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-06 00:07:30 +08:00
										 |  |  | An `ErrorResponse` may expose more than one message code, typically adding a suffix | 
					
						
							| 
									
										
										
										
											2023-06-14 22:57:04 +08:00
										 |  |  | to the default message code. The table below lists message codes, and arguments for | 
					
						
							|  |  |  | Spring WebFlux exceptions: | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | [[webflux-ann-rest-exceptions-codes]] | 
					
						
							|  |  |  | [cols="1,1,2", options="header"] | 
					
						
							|  |  |  | |=== | 
					
						
							|  |  |  | | Exception | Message Code | Message Code Arguments | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-06 00:07:30 +08:00
										 |  |  | | `HandlerMethodValidationException` | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | | (default) | 
					
						
							| 
									
										
										
										
											2023-07-06 00:07:30 +08:00
										 |  |  | | `+{0}+` list all validation errors. | 
					
						
							|  |  |  | Message codes and arguments for each error are also resolved via `MessageSource`. | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-06 00:07:30 +08:00
										 |  |  | | `MethodNotAllowedException` | 
					
						
							|  |  |  | | (default) | 
					
						
							|  |  |  | | `+{0}+` the current HTTP method, `+{1}+` the list of supported HTTP methods | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | | `MissingRequestValueException` | 
					
						
							|  |  |  | | (default) | 
					
						
							| 
									
										
										
										
											2023-04-19 05:37:25 +08:00
										 |  |  | | `+{0}+` a label for the value (e.g. "request header", "cookie value", ...), `+{1}+` the value name | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | | `NotAcceptableStatusException` | 
					
						
							|  |  |  | | (default) | 
					
						
							| 
									
										
										
										
											2023-04-19 05:37:25 +08:00
										 |  |  | | `+{0}+` list of supported media types | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | | `NotAcceptableStatusException` | 
					
						
							|  |  |  | | (default) + ".parseError" | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | | `ServerErrorException` | 
					
						
							|  |  |  | | (default) | 
					
						
							| 
									
										
										
										
											2023-04-19 05:37:25 +08:00
										 |  |  | | `+{0}+` the failure reason provided to the class constructor | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-06 00:07:30 +08:00
										 |  |  | | `UnsupportedMediaTypeStatusException` | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | | (default) | 
					
						
							| 
									
										
										
										
											2023-07-06 00:07:30 +08:00
										 |  |  | | `+{0}+` the media type that is not supported, `+{1}+` list of supported media types | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | | `UnsupportedMediaTypeStatusException` | 
					
						
							|  |  |  | | (default) + ".parseError" | 
					
						
							|  |  |  | | | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | | `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 are also resolved via `MessageSource`. | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | |=== | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-08 04:31:58 +08:00
										 |  |  | NOTE: Unlike other exceptions, the message arguments for | 
					
						
							|  |  |  | `WebExchangeBindException` and `HandlerMethodValidationException` are based on a list of | 
					
						
							|  |  |  | `MessageSourceResolvable` errors that can also be customized through a | 
					
						
							|  |  |  | xref:core/beans/context-introduction.adoc#context-functionality-messagesource[MessageSource] | 
					
						
							|  |  |  | resource bundle. See | 
					
						
							|  |  |  | xref:core/validation/beanvalidation.adoc#validation-beanvalidation-spring-method-i18n[Customizing Validation Errors] | 
					
						
							|  |  |  | for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [[webflux-ann-rest-exceptions-client]] | 
					
						
							|  |  |  | == Client Handling | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:17 +08:00
										 |  |  | [.small]#xref:web/webmvc/mvc-ann-rest-exceptions.adoc#mvc-ann-rest-exceptions-client[See equivalent in the Servlet stack]# | 
					
						
							| 
									
										
										
										
											2023-04-19 23:26:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |