code: private RuntimeException throwIfPossible(Throwable t) throws IOException, ChannelException
    {
      Preconditions.checkNotNull(t, "Throwable shoulnd't null");
  
      if (t instanceof ExecutionException) {
        if (t.getCause() != null) {
          return throwIfPossible(t.getCause());
        } else {
          return new RuntimeException(t);
        }
      }
  
      if (t instanceof IOException) {
        throw (IOException) t;
      }
  
      if (t instanceof ChannelException) {
        throw (ChannelException) t;
      }
  
      if (t instanceof InterruptedException) {
        Thread.currentThread().interrupt();
        throw new RuntimeException(t);
      }
  
      Throwables.propagateIfPossible(t);
      return new RuntimeException(t);
    }
docs: Throws if it's possible to throw the given Throwable.
  <p>
  - The input throwable shouldn't be null.
  - If Throwable is an {@link ExecutionException}, this calls itself recursively with the cause of ExecutionException.
  - If Throwable is an {@link IOException} or a {@link ChannelException}, this simply throws it.
  - If Throwable is an {@link InterruptedException}, this interrupts the current thread and throws a RuntimeException
  wrapping the InterruptedException
  - Otherwise, this simply returns the given Throwable.
  <p>
  Note that if the given Throable is an ExecutionException, this can return the cause of ExecutionException.