Reputation: 4282
In Spring Webflux what is the prefered way of Exception Handling?
@RestControllerAdvice comes from Spring MVC whereas DefaultErrorAttributes comes from Spring Webflux.
However, in Spring Webflux someone could use @RestControllerAdvice. What would be the advantages/disadvantages?
@RestControllerAdvice
@RestControllerAdvice
public class ControllerAdvice
{
@ExceptionHandler(Throwable.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Mono<Map<String, Object>> exceptions(Throwable e)
{
return Mono.just(Map.of("message", "bad"));
}
}
Extend DefaultErrorAttributes
@Component
public class ErrorAttributes extends DefaultErrorAttributes
{
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace)
{
var ex = getError(request);
var attributes = new LinkedHashMap<String, Object>();
attributes.put("status", HttpStatus.BAD_REQUEST.value());
attributes.put("message", "bad");
return attributes;
}
}
I want to stay in the reactive world, so I tend more towards DefaultErrorAttributes (which plays well with DefaultErrorWebExceptionHandler in Webflux). However, in @RestControllerAdvice I could also use Mono.just(...).
Upvotes: 7
Views: 9324
Reputation: 827
In Spring Webflux in case functional routes declaration, you can also implement your own ExceptionHandler instead of DefaultErrorWebExceptionHandler:
class SystemErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) {
return super.handle(exchange, throwable)
// debug, process
.contextWrite(...);
}
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
// for all routs
return route(all(), this::renderErrorResponse);
}
private Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
Map<String, Object> error = getErrorAttributes(request, ErrorAttributeOptions.of());
Throwable t = this.getError(request);
// map exception on response
return ServerResponse.status(status).body(...);
}
}
Then use your implementation of AbstractErrorWebExceptionHandler in the spring configuration with @AutoConfigureBefore(WebFluxAutoConfiguration.class)
Upvotes: 0
Reputation: 1092
It is same. Like WebMvc.
@RestControllerAdvice
public class ControllerAdvice {
@ExceptionHandler(AnyException.class)
public Mono<EntityResponse<YourModel>> example(AnyException exception) {
return EntityResponse.fromObject(new YourModel()).status(HttpStatus.NOT_FOUND).build();
}
}
Upvotes: 2