Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access the RequestBody in a Spring WebFlux @ExceptionHandler?

Is there a way to get access to the RequestBody (preferably in it's mapped form) in an @ExceptionHandler method using Spring WebFlux, with the default Reactor Netty?

Consider the following example:

@RestController
class TestRestController {

  @PostMapping("/test")
  Mono<TestBody> testPost(@RequestBody TestBody testBody) {
    return Mono.error(new NullPointerException());
  }

  @ExceptionHandler(NullPointerException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  Mono<Void> handleNullPointerException(ServerWebExchange serverWebExchange) {
    return Mono.empty();
  }

}

At runtime additional instances of certain types can be injected into the @ExceptionHandler's method signature, as shown in the above example with ServerWebExchange. But the docs clearly state that it doesn't support request body arguments (see the note in this section).

Using the Servlet stack, you can inject the RequestContext as shown here. Is there an equivalent or similar approach for the WebFlux stack?

like image 819
peterl Avatar asked Nov 06 '22 08:11

peterl


1 Answers

Yes, there is a way, but not a really good looking one. We had kind of the same problem, but in our case we've wanted to have access on the reactive context, since we've stubbornly chose to use the MDC in this reactive paradigm, so the MDC rely on that context.

After lots of back-and-forth with the Exception handlers and controller advice, it was pretty obvious that the reactive context could not be accessed there.

So we've extends the AbstractErrorWebExceptionHandler . Here there is a handle(ServerWebExchange exchange, Throwable throwable) method that will be called when you're application has an error. The good part is that there is the ServerWebExchange and you can access the context like: exchange.getAttributes().get(MDC_CONTEXT) or the body like: exchange.getRequest().getBody().

So that resolved our MDC problem, but the mapping of the errors had to be handled manually unfortunately. I've remember that we've invested a lot of time, and at that time, that was the best solution. Cheers!

like image 165
brebDev Avatar answered Nov 15 '22 06:11

brebDev