title: WebClient - logging & handling 4xx, 5xx and additional error responses
body: <h2>Context</h2>
  <p>I am using WebClient (synchronous mode) to conduct calls to several external API services.
  In the event of failure, be it a connection, SSL or any 4xx/5xx error (essentially, <a href="https://stackoverflow.com/a/55778923">any error mentioned in this list</a>), the external service <em>may</em> return a response body with a proper error description.
  TODO: add that we want to tackle both API errors and communication errors (errors where the response body may be empty)</p>
  <p>Goal:
  In the event of external service failure, I would like to log the response body and status code accordingly, and send an exception back in the form of a 500 error, to the consumer of our service.</p>
  <h2>Problem</h2>
  <p>I want to be able to log the external service API response body's in case of 4xx/5xx failures, but would also like to log errors related to the communication with the external API: be it changing the port of the external service, or SSL related connection problems.
  So in essence, is it possible to handle both the exception message and response body at the same time?</p>
  <p><strong>Example</strong></p>
  <p>The external service returns the following response body with 401 as status code:</p>
  <pre><code>{
      &quot;error&quot;: &quot;invalid client certificate used&quot;
  }
  </code></pre>
  <h2>Code</h2>
  <p>The following code does not show the specific error message at all:</p>
  <pre><code>public String callExternalAPI() {
      final HttpStatus[] statuses = {HttpStatus.OK};
      try {
          String response =  webClientLogon.post()
              .uri(builder -&gt; builder.path(myExternalServiceURL).build())
              .headers(this::myHeaders)
              .exchangeToMono(res -&gt;{if (res.statusCode().equals(HttpStatus.OK)) {
                  return res.bodyToMono(String.class);
              } else if (res.statusCode().isError()) {
                  statuses[0] = res.statusCode();
                  return res.bodyToMono(String.class);
              } else {
                  statuses[0] = res.statusCode();
                  return res.bodyToMono(String.class);
              }})
              .block();
          return handleResponse(response, statuses[0]);
      } catch (WebClientException ex){
          throw handleWebClientException(ex);
      }
  }
  </code></pre>