Handling Web Exceptions¶
When exposing RESTful APIs you can choose between @RestController and functional RouterFunction routes.
The former is simple. If you have some experience with Spring WebMvc, it is easy to update your knowledge. Just need to use newer Reactor specific Mono and Flux instead in your codes.
The exception handling in reactive @RestController is similar to the one in WebMVC.
-
Create an
Exceptionclass. -
Throw exception in your codes.
-
Create a standalone
@ControllerAdviceannotated class or@ExceptionHandlerannotated method in your controller class to handle the exceptions.
@RestControllerAdvice only works for @RestController.
If you are using RouterFunction, create a WebExceptionHandler bean to handle it manually.
@Bean
public WebExceptionHandler exceptionHandler() {
return (ServerWebExchange exchange, Throwable ex) -> {
if (ex instanceof PostNotFoundException) {
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
return exchange.getResponse().setComplete();
}
return Mono.error(ex);
};
}
Note
WebExceptionHandler is a low-level API. It also works for the exception handling in the annotated controller case — the @ExceptionHandler mechanism itself is implemented as a chain of WebExceptionHandlers.
Registering a WebExceptionHandler in Spring Boot¶
In a Spring Boot application, register the handler as a @Component with an explicit @Order(-2) so it runs before the default ErrorWebExceptionHandler (which has order -1):
@Component
@Order(-2)
class RestWebExceptionHandler implements WebExceptionHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
if (ex instanceof PostNotFoundException) {
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
// marks the response as complete and forbids writing to it
return exchange.getResponse().setComplete();
}
return Mono.error(ex);
}
}
You can explore the complete codes in spring-reactive-sample/exception-handler and spring-reactive-sample/boot-exception-handler.
Tip
Spring supports the standard error response format defined by RFC 9457. See Problem Details for the ProblemDetail based approach.