title: Does an exception handler passed to CompletableFuture.exceptionally() have to return a meaningful value?
body: <p>I'm used to the <a href="https://github.com/google/guava/wiki/ListenableFutureExplained" rel="noreferrer"><code>ListenableFuture</code></a> pattern, with <code>onSuccess()</code> and <code>onFailure()</code> callbacks, e.g.</p>
  
  <pre><code>ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
  ListenableFuture&lt;String&gt; future = service.submit(...)
  Futures.addCallback(future, new FutureCallback&lt;String&gt;() {
    public void onSuccess(String result) {
      handleResult(result);
    }
    public void onFailure(Throwable t) {
      log.error("Unexpected error", t);
    }
  })
  </code></pre>
  
  <p>It seems like Java 8's <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html" rel="noreferrer"><code>CompletableFuture</code></a> is meant to handle more or less the same use case. Naively, I could start to translate the above example as:</p>
  
  <pre><code>CompletableFuture&lt;String&gt; future = CompletableFuture&lt;String&gt;.supplyAsync(...)
    .thenAccept(this::handleResult)
    .exceptionally((t) -&gt; log.error("Unexpected error", t));
  </code></pre>
  
  <p>This is certainly less verbose than the <code>ListenableFuture</code> version and looks very promising.</p>
  
  <p>However, it doesn't compile, because <code>exceptionally()</code> doesn't take a <code>Consumer&lt;Throwable&gt;</code>, it takes a <code>Function&lt;Throwable, ? extends T&gt;</code> -- in this case, a <code>Function&lt;Throwable, ? extends String&gt;</code>.</p>
  
  <p>This means that I can't just log the error, I have to come up with a <code>String</code> value to return in the error case, and there is no meaningful <code>String</code> value to return in the error case. I can return <code>null</code>, just to get the code to compile:</p>
  
  <pre><code>  .exceptionally((t) -&gt; {
      log.error("Unexpected error", t);
      return null; // hope this is ignored
    });
  </code></pre>
  
  <p>But this is starting to get verbose again, and beyond verbosity, I don't like having that <code>null</code> floating around -- it suggests that someone might try to retrieve or capture that value, and that at some point much later I might have an unexpected <code>NullPointerException</code>.</p>
  
  <p>If <code>exceptionally()</code> took a <code>Function&lt;Throwable, Supplier&lt;T&gt;&gt;</code> I could at least do something like this --</p>
  
  <pre><code>  .exceptionally((t) -&gt; {
      log.error("Unexpected error", t);
      return () -&gt; { 
        throw new IllegalStateException("why are you invoking this?");
      }
    });
  </code></pre>
  
  <p>-- but it doesn't.</p>
  
  <p>What's the right thing to do when <code>exceptionally()</code> should never produce a valid value? Is there something else I can do with <code>CompletableFuture</code>, or something else in the new Java 8 libraries, that better supports this use case?</p>