title: Catch exceptions with try/catch using Spring's WebClient with blocking/syncronous request
body: <p>I need to make a <strong>syncronous, blocking</strong> request, and I'm using Spring's <code>WebClient</code> instead of Spring's <code>RestTemplate</code> due to the latter being deprecated. I don't need the reactive features in this case, I just want to consume a REST API in a straightforward way without including additional dependencies.</p>
  <p>I have the following code, which works as intended:</p>
  <pre><code>MyObject object = webClient.get()
      .uri( myUri )
      .retrieve()
      .bodyToMono( MyObject.class )
      .block()
  </code></pre>
  <p>However, I need to manage the cases when I either can't connect to the API, or if I connect but I get a 4xx/5xx code.</p>
  <p>So, the straightforward way would be to just put the call inside a try/catch, and catch Spring's <code>WebClientResponseException</code>, which is thrown by <code>.bodyToMono</code> if it gets a 4xx/5xx code:</p>
  <pre><code>import org.springframework.web.reactive.function.client.WebClientResponseException;
  
  try {
  
      MyObject object = webClient.get()
          .uri( myUri )
          .retrieve()
          .bodyToMono( MyObject.class )
          .block()
  
  }
  
  catch ( WebClientResponseException e ) {
  
      // Logic to handle the exception.
  
  }
  </code></pre>
  <p>This works fine, but doesn't work if the connection is refused (say, if the URL is wrong or if the service is down). In this case, I get the following in my console:</p>
  <blockquote>
  <p>reactor.core.Exceptions$ErrorCallbackNotImplemented:
  io.netty.channel.AbstractChannel$AnnotatedConnectException:
  finishConnect(..) failed: Connection refused: /127.0.0.1:8090 Caused
  by: io.netty.channel.AbstractChannel$AnnotatedConnectException:
  finishConnect(..) failed: Connection refused: /127.0.0.1:8090
  Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:  Error has
  been observed at the following site(s):
  |_ checkpoint ⇢ Request to GET <a href="http://127.0.0.1:8090/test" rel="noreferrer">http://127.0.0.1:8090/test</a> [DefaultWebClient] Stack trace: Caused by: java.net.ConnectException:
  finishConnect(..) failed: Connection refused
  at io.netty.channel.unix.Errors.throwConnectException(Errors.java:124)
  ~[netty-transport-native-unix-common-4.1.48.Final.jar:4.1.48.Final]
  (...)</p>
  </blockquote>
  <p>I'm not sure which exception I need to catch to handle this case.</p>
  <p>Besides the above, I also would like to throw a custom exception if the connection is refused and a different custom exception if I get an error code. In the second case, I tried using the <code>.onStatus</code> method:</p>
  <pre><code>try {
  
      MyObject object = webClient.get()
          .uri( myUri )
          .retrieve()
          .onStatus( HttpStatus::is4xxClientError, response -&gt; { 
              return Mono.error( new CustomClientException( &quot;A client error ocurred&quot; ) );
          })
          .bodyToMono( MyObject.class )
          .block()
  
  }
  
  catch ( CustomClientException e ) {
  
      // Logic to handle the exception.
  
  }
  </code></pre>
  <p>But the exception is not caught inside the catch block, although the stack trace does appear on console.</p>
  <p>Is there any way to handle 4xx/5xx codes and connection errors using a try/catch block, hopefully with custom exceptions? Or should I use a different web client and/or change my approach? I'm not familiar with reactive programming.</p>
  <p>Thanks in advance.</p>