naturzukunft
naturzukunft

Reputation: 127

handling error messages with spring-boot webflux

i'm writing a java adapter for posting something to a webService. In the http service i use an ExceptionHandler:

@org.springframework.web.bind.annotation.ExceptionHandler 
public ResponseEntity<String> handle(BadCommandException ex) {
  return ResponseEntity.badRequest().body(ex.getMessage());
}

That works well, if i call it with curl/postman.

But how can i get the error message that is in the body with a reactive WebClient ?
Part of my client-lib:

private Mono<Optional<String>> post(String bearerToken, Model model, IRI outbox) {
    return WebClient.builder()
        .build()
        .post()
        .uri(outbox.stringValue())
        .contentType(new MediaType("text","turtle"))
        .body(BodyInserters.fromValue(modelToTurtleString(model)))              
        .header("Authorization", "Bearer " + bearerToken)
        .header("profile", "https://www.w3.org/ns/activitystreams")
        .accept(new MediaType("text", "turtle"))
        .retrieve()         
        .toEntity(String.class)
        .map(res->res.getHeaders().get("Location").stream().findFirst());
}

In success case, i want to return the string from the location header. But how can i for example throw an Exception if the http-status is 400 and add the error message from the body to the exception?

Thanks

Upvotes: 0

Views: 1026

Answers (2)

naturzukunft
naturzukunft

Reputation: 127

.onStatus(HttpStatus::is4xxClientError,
    clientResponse -> { return clientResponse.createException(); 

Javadoc:

/**
 * Create a {@link WebClientResponseException} that contains the response
 * status, headers, body, and the originating request.
 * @return a {@code Mono} with the created exception
 * @since 5.2
 */
Mono<WebClientResponseException> createException();

My problem was my testcase 'test bad request'. Because of a refactoring it was sending an empty request body instead of a bad one and the annotation @RequestBody has an attribute 'required' which is default true. So the response body was always empty and did not contain my error message as expected ;-)

public Mono<ResponseEntity<Void>> doIt(Principal principal, @PathVariable String actorId, @RequestBody String model) {
...

that cost me hours ;-)

Upvotes: 0

Toerktumlare
Toerktumlare

Reputation: 14712

the spring documentation on webclient retreive() has examples of how to handle errors. I suggest you start there.

Mono<Person> result = client.get()
        .uri("/persons/{id}", id).accept(MediaType.APPLICATION_JSON)
        .retrieve()
        .onStatus(HttpStatus::is4xxClientError, response -> ...)
        .onStatus(HttpStatus::is5xxServerError, response -> ...)
        .bodyToMono(Person.class);

Upvotes: 1

Related Questions