public static Exception extractFutureExceptionCause(Throwable throwable) {
    if (throwable == null) {
      return null;
    }
    while ((throwable instanceof CompletionException || throwable instanceof ExecutionException)
        && throwable.getCause() != null) {
      // Extract nested exception for CompletionException and ExecutionException
      throwable = throwable.getCause();
    }
    return throwable instanceof Exception ? (Exception) throwable : new Exception(throwable);
  }
Extracts the cause of an {@link ExecutionException} or {@link CompletionException}. This is used to get the
relevant domain-specific exception after unboxing various types of futures.
@param throwable the {@link Throwable}
@return If the supplied throwable is null, return null.
        If not {@link ExecutionException} or {@link CompletionException}, return throwable itself.
        If the cause is {@code null}, return {@code throwable} itself.
        If the cause or original throwable is not an instance of exception, return the {@link Throwable} wrapped
        in an exception. Otherwise, return the cause {@link Exception}.
ambry-utils/src/main/java/com/github/ambry/utils/Utils.java