title: How to catch exceptions with the CompletableFuture class in REST web services and Spring?
body: <p>I have developed some async web services with spring framework and REST, I have consumed it from a client created with spring class <code>AsyncRestTemplate</code>. Class return an object <code>ListenableFuture&lt;ResponseEntity&lt;T&gt;&gt;</code> (with the method <code>getForEntity</code>), which brings the value returned by the web service (with the method <code>.get():&lt;T&gt;</code>) . It works fine, however when occurs an custom exception in the REST web service (which extends <code>RuntimeException</code> class) the client does not catch it correctly and it show me the follow message:</p>
  
  <blockquote>
    <p>"timestamp": "2018-05-28T14:25:15.393+0000",    "status": 500,<br>
    "error": "Internal Server Error",    "message":
    "java.util.concurrent.ExecutionException:
    org.springframework.web.client.HttpServerErrorException: 500 null",<br>
    "path": "/client/result"</p>
  </blockquote>
  
  <p>Does someone knows how can i solve the problem?. I want the client shows me the custom exception message.</p>
  
  <p>The server codes are the following:</p>
  
  <p>Configuration Class:</p>
  
  <pre><code>@Configuration
  @EnableAsync
  public class ConfigurationClass {
      @Bean
      public Executor threadPoolTaskExecutor() {
          return new ThreadPoolTaskExecutor();
      }
  }
  </code></pre>
  
  <p>Controller class:</p>
  
  <pre><code>@RestController
  @RequestMapping("/server")
  public class ControllerClass {
  
      @GetMapping("/start")
      @Async
      public CompletableFuture&lt;String&gt;  callService() throws InterruptedException{
          Thread.sleep(10000L);
          if(true)
              throw new RuntimeException("Custom Error");
          return CompletableFuture.completedFuture("OK");
      }
  }
  </code></pre>
  
  <p>The client code (consumer) is the following:</p>
  
  <pre><code>@RestController
  @RequestMapping("/client")
  public class ControllerClass {
  
      private ListenableFuture&lt;ResponseEntity&lt;String&gt;&gt; entity;
  
      @GetMapping("/start")
      @Async
      public void callService() throws InterruptedException {
          AsyncRestTemplate restTemplate = new AsyncRestTemplate();
          entity = restTemplate.getForEntity("http://localhost:8080/server/start",
                   String.class);
      }
  
      @GetMapping("/state")
      public boolean getState() {
          try {
              return entity.isDone();
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
      }
  
      @GetMapping("/result")
      public ResponseEntity&lt;String&gt; getResult() {
          try {
              return entity.get();
  
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
      }
  }
  </code></pre>
  
  <p>Thanks for your help, Regards.</p>
  
  <p>Is was added 19/05/2018---------------------------------------</p>
  
  <p>I'm close to the solution. In the control class of web service I added the method annotated with <code>@ExceptionHandler</code>,Like in the follows code:</p>
  
  <pre><code>@ExceptionHandler(RuntimeException.class)
      void handleIllegalArgumentException(HttpServletResponse response) throws IOException {
          response.sendError(200, "custom Error");
      }
  </code></pre>
  
  <p>It works fine, the client has already recognized the exception 
  correctly, however, if I change the status by other in the web service (like 201, 400, 401, which are <a href="https://www.w3schools.com/tags/ref_httpmessages.asp" rel="nofollow noreferrer">HTTP valid status</a>),
  I go back to get the message <code>"java.util.concurrent.ExecutionException: org.springframework.web.client.HttpServerErrorException: 500 null"</code>, in the client.  </p>
  
  <p>Does someone knows the reason?</p>