4

I use this code to send XML requests:

RestClient client = RestClientBuilder.builder()
                        .gatewayUrl(URL) 
                        .build();
Mono<AuthorizeResponse> result = client.executeAndReceiveAuthorize(request);
                response = result.block();

 public RestClient(String gatewayUrl, String token, String username, String password, SslContext sslContext) {
        this.token = token;
        this.gatewayUrl = gatewayUrl;
        WebClient.Builder builder = WebClient.builder().baseUrl(gatewayUrl);
        if (sslContext != null) {
            HttpClient httpClient = HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
            ClientHttpConnector httpConnector = new ReactorClientHttpConnector(httpClient);
            builder.clientConnector(httpConnector);
        }
        if (username != null && password != null) {
            builder.filter(basicAuthentication(username, password));
        }
        client = builder.build();
    }

    public Mono<AuthorizeResponse> executeAndReceiveAuthorize(AuthorizeRequest transaction) {
        Mono<AuthorizeRequest> transactionMono = Mono.just(transaction);
        return client.post().uri(checkTrailingSlash(gatewayUrl) + token)
                .header(HttpHeaders.USER_AGENT, "Mozilla/5.0")
                .accept(MediaType.APPLICATION_XML)
                .contentType(MediaType.APPLICATION_XML)
                .body(transactionMono, AuthorizeRequest.class)
                .retrieve()
                .bodyToMono(AuthorizeResponse.class);
    }

But sometimes I get this error:

org.springframework.web.reactive.function.client.WebClientResponseException$Unauthorized: 401 Unauthorized
 at java.base/java.lang.Thread.run(Thread.java:834)
2019-08-27 22:05:45,720 ERROR [stderr] (processingTransactionGenesisAuthorizeContainer-1)       Suppressed: java.lang.Exception: #block terminated with an error
 Caused by: java.lang.NullPointerException: null

How I can catch and process the exception when I get error 401? If it's possible I would like to process the exception after the line response = result.block();.

Peter Penzov
  • 1,126
  • 134
  • 430
  • 808

2 Answers2

2

The very first thing is that it is not a good idea to use block explicitly in your reactive code. The reason behind this is, it turns the code into blocking and that is not how reactive streams are supposed to work. So, please remove response = result.block();

Now, if you want to process a particular status then you can modify your executeAndReceiveAuthorize method to use WebClient's onStatus(Predicate<HttpStatus> var1, Function<ClientResponse, Mono<? extends Throwable>> var2)

public Mono<AuthorizeResponse> executeAndReceiveAuthorize (AuthorizeRequest transaction){

    Mono<AuthorizeRequest> transactionMono = Mono.just(transaction);

    return client.post().uri(checkTrailingSlash(gatewayUrl) + token)
        .header(HttpHeaders.USER_AGENT, "Mozilla/5.0").accept(MediaType.APPLICATION_XML)
        .contentType(MediaType.APPLICATION_XML).body(transactionMono, AuthorizeRequest.class)
        .retrieve().onStatus(status -> status == HttpStatus.UNAUTHORIZED, clientResponse -> Mono
            .error(new SomeCustomAuthorizationException("Some failure exception")))
        .bodyToMono(AuthorizeResponse.class);
}
isank-a
  • 1,545
  • 2
  • 17
  • 22
0

What about defining a doOnError on the mono?

For example:

Mono<AuthorizeResponse> result = client.executeAndReceiveAuthorize(request);
response = result.doOnError(e -> {
                      throw new RuntimeException(e);
                  })
                 .block();

Also check this answer in case you need access to the json response.

second
  • 4,069
  • 2
  • 9
  • 24
  • `doOnError` is a side effect method in Spring Webflux and should not be used for these purposes. It's more suitable for logging related works. Also, throwing exceptions is a bad idea and we should wrap exceptions like `return Mono.error(new Exception())` – isank-a Oct 07 '19 at 06:33
  • The throwing of the exception is just a sample for doing something with the exception. The important part is that the exception is passed into the `doOnError` method and can be obtained from there. `@PeterPenzov` didn't really specify what he wants to di with the exception, maybe logging it is sufficient. – second Oct 09 '19 at 21:49