title: How to pass checked exception from CompletableFuture to ControllerAdvice
body: <p>How can I make the controllerAdvice class catch the exception that is thrown from completablefutrue. 
  In the code below I have a method <code>checkId</code> that throws a checked exception. I call this method using completablefuture and wrap the checked exception inside CompletionException. Although I have a handler method in controller advice class, but it didn't handle the error.</p>
  
  <pre><code>package com.example.demo.controller;
  @RestController
  public class HomeController {
  
      @GetMapping(path = "/check")
      public CompletableFuture&lt;String&gt; check(@RequestParam("id") int id) {
          return CompletableFuture.supplyAsync(() -&gt; {
              try {
                  return checkId(id);
              }
              catch (Exception e) {
                  throw new CompletionException(e);
              }
          });
      }
  
      public String checkId(int id) throws Exception  {
          if (id &lt; 0) {
              throw new MyException("Id must be greater than 0");
          }
          return "id is good";
      }
  
  }
  </code></pre>
  
  <p>-</p>
  
  <pre><code>package com.example.demo;
  public class MyException extends Exception {
  
      public MyException(String message) {
          super(message);
      }
  
  }
  </code></pre>
  
  <p>-</p>
  
  <pre><code>package com.example.demo;
  @ControllerAdvice
  public class ExceptionResolver {
  
      @ExceptionHandler(value = CompletionException.class)
      public String handleCompletionException(CompletionException ex) {
          return ex.getMessage();
      }
  
  }
  </code></pre>
  
  <p>--</p>
  
  <pre><code>package com.example.demo;
  @SpringBootApplication
  public class DemoApplication {
  
      public static void main(String[] args) {
          SpringApplication.run(DemoApplication.class, args);
      }
  
  }
  </code></pre>
  
  <p>Stack trace:</p>
  
  <pre><code>com.example.demo.MyException: Id must be greater than 0
      at com.example.demo.controller.HomeController.checkId(HomeController.java:30) ~[classes/:na]
      at com.example.demo.controller.HomeController.lambda$0(HomeController.java:19) ~[classes/:na]
      at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700) ~[na:na]
      at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1692) ~[na:na]
      at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) ~[na:na]
      at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) ~[na:na]
      at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) ~[na:na]
      at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) ~[na:na]
      at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177) ~[na:na]
  
  2020-01-24 14:38:30.489 ERROR 938 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.example.demo.MyException: Id must be greater than 0] with root cause
  
  com.example.demo.MyException: Id must be greater than 0
      at com.example.demo.controller.HomeController.checkId(HomeController.java:30) ~[classes/:na]
      at com.example.demo.controller.HomeController.lambda$0(HomeController.java:19) ~[classes/:na]
      at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700) ~[na:na]
      at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1692) ~[na:na]
      at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) ~[na:na]
      at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) ~[na:na]
      at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) ~[na:na]
      at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) ~[na:na]
      at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177) ~[na:na]
  </code></pre>