@SuppressWarnings("FutureReturnValueIgnored")
  public static <T> void addListener(CompletableFuture<T> future,
    BiConsumer<? super T, ? super Throwable> action) {
    future.whenComplete((resp, error) -> {
      try {
        // See this post on stack overflow(shorten since the url is too long),
        // https://s.apache.org/completionexception
        // For a chain of CompleableFuture, only the first child CompletableFuture can get the
        // original exception, others will get a CompletionException, which wraps the original
        // exception. So here we unwrap it before passing it to the callback action.
        action.accept(resp, unwrapCompletionException(error));
      } catch (Throwable t) {
        LOG.error("Unexpected error caught when processing CompletableFuture", t);
      }
    });
  }
This is method is used when you just want to add a listener to the given future. We will call
{@link CompletableFuture#whenComplete(BiConsumer)} to register the {@code action} to the
{@code future}. Ignoring the return value of a Future is considered as a bad practice as it may
suppress exceptions thrown from the code that completes the future, and this method will catch
all the exception thrown from the {@code action} to catch possible code bugs.
<p/>
And the error phone check will always report FutureReturnValueIgnored because every method in
the {@link CompletableFuture} class will return a new {@link CompletableFuture}, so you always
have one future that has not been checked. So we introduce this method and add a suppress
warnings annotation here.
hbase-common/src/main/java/org/apache/hadoop/hbase/util/FutureUtils.java