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.
public class PostNotFoundException extends RuntimeException {
public PostNotFoundException(Long id) {
super("Post:" + id +" is not found.");
}
}
- Throw exception in your codes.
@GetMapping(value = "/{id}")
public Mono<Post> get(@PathVariable(value = "id") Long id) {
return this.posts.findById(id).switchIfEmpty(Mono.error(new PostNotFoundException(id)));
}
- Create a standalone
@ControllerAdviceannotated class or@ExceptionHandlerannotated method in your controller class to handle the exceptions.
@RestControllerAdvice
@Slf4j
class RestExceptionHandler {
@ExceptionHandler(PostNotFoundException.class)
public ResponseEntity<?> postNotFound(PostNotFoundException ex) {
log.debug("handling exception: {}", ex.toString());
return ResponseEntity.notFound().build();
}
}
@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 extension point. For most cases prefer @RestControllerAdvice or functional exception handlers.
NOTE:
WebExceptionHandleris a low-level API, also works well for the exception handling in the former controller case.
For the complete codes, check spring-reactive-sample/exception-handler and spring-reactive-sample/boot-exception-handler .