Ensure SettableFutures in remote module are all set.

Failed doing so, will cause Bazel hanging forever. This could be one of causes for #11782.

Closes #12426.

PiperOrigin-RevId: 341554621
diff --git a/src/main/java/com/google/devtools/build/lib/remote/GrpcCacheClient.java b/src/main/java/com/google/devtools/build/lib/remote/GrpcCacheClient.java
index 776f995..2e783ca 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/GrpcCacheClient.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/GrpcCacheClient.java
@@ -37,6 +37,7 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
+import com.google.common.flogger.GoogleLogger;
 import com.google.common.hash.HashCode;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -73,6 +74,8 @@
 /** A RemoteActionCache implementation that uses gRPC calls to a remote cache server. */
 @ThreadSafe
 public class GrpcCacheClient implements RemoteCacheClient, MissingDigestsFinder {
+  private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
+
   private final CallCredentialsProvider callCredentialsProvider;
   private final ReferenceCountedChannel channel;
   private final RemoteOptions options;
@@ -345,7 +348,6 @@
                   data.writeTo(out);
                   offset.addAndGet(data.size());
                 } catch (IOException e) {
-                  future.setException(e);
                   // Cancel the call.
                   throw new RuntimeException(e);
                 }
@@ -373,6 +375,9 @@
                   future.set(null);
                 } catch (IOException e) {
                   future.setException(e);
+                } catch (RuntimeException e) {
+                  logger.atWarning().withCause(e).log("Unexpected exception");
+                  future.setException(e);
                 }
               }
             });
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteCache.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteCache.java
index 659d9a1..511c5bd 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteCache.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteCache.java
@@ -35,6 +35,7 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
+import com.google.common.flogger.GoogleLogger;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -92,6 +93,7 @@
 /** A cache for storing artifacts (input and output) as well as the output of running an action. */
 @ThreadSafety.ThreadSafe
 public class RemoteCache implements AutoCloseable {
+  private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
 
   /** See {@link SpawnExecutionContext#lockOutputFiles()}. */
   @FunctionalInterface
@@ -265,7 +267,12 @@
         new FutureCallback<Void>() {
           @Override
           public void onSuccess(Void aVoid) {
-            outerF.set(bOut.toByteArray());
+            try {
+              outerF.set(bOut.toByteArray());
+            } catch (RuntimeException e) {
+              logger.atWarning().withCause(e).log("Unexpected exception");
+              outerF.setException(e);
+            }
           }
 
           @Override
@@ -471,6 +478,9 @@
               outerF.set(null);
             } catch (IOException e) {
               outerF.setException(e);
+            } catch (RuntimeException e) {
+              logger.atWarning().withCause(e).log("Unexpected exception");
+              outerF.setException(e);
             }
           }
 
@@ -482,6 +492,9 @@
               if (t != e) {
                 t.addSuppressed(e);
               }
+            } catch (RuntimeException e) {
+              logger.atWarning().withCause(e).log("Unexpected exception");
+              t.addSuppressed(e);
             } finally {
               outerF.setException(t);
             }
diff --git a/src/main/java/com/google/devtools/build/lib/remote/http/BUILD b/src/main/java/com/google/devtools/build/lib/remote/http/BUILD
index 8fd1c63..9ce71c7 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/http/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/remote/http/BUILD
@@ -23,6 +23,7 @@
         "//src/main/java/com/google/devtools/build/lib/remote/util",
         "//src/main/java/com/google/devtools/build/lib/vfs",
         "//third_party:auth",
+        "//third_party:flogger",
         "//third_party:guava",
         "//third_party:jsr305",
         "//third_party:netty",
diff --git a/src/main/java/com/google/devtools/build/lib/remote/http/HttpCacheClient.java b/src/main/java/com/google/devtools/build/lib/remote/http/HttpCacheClient.java
index 18b0f81..bdfca85 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/http/HttpCacheClient.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/http/HttpCacheClient.java
@@ -19,6 +19,7 @@
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.flogger.GoogleLogger;
 import com.google.common.io.Closeables;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -113,6 +114,7 @@
  * <p>The implementation currently does not support transfer encoding chunked.
  */
 public final class HttpCacheClient implements RemoteCacheClient {
+  private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
 
   public static final String AC_PREFIX = "ac/";
   public static final String CAS_PREFIX = "cas/";
@@ -508,9 +510,16 @@
                               if (!dataWritten.get() && authTokenExpired(response)) {
                                 // The error is due to an auth token having expired. Let's try
                                 // again.
-                                refreshCredentials();
-                                getAfterCredentialRefresh(downloadCmd, outerF);
-                                return;
+                                try {
+                                  refreshCredentials();
+                                  getAfterCredentialRefresh(downloadCmd, outerF);
+                                  return;
+                                } catch (IOException e) {
+                                  cause.addSuppressed(e);
+                                } catch (RuntimeException e) {
+                                  logger.atWarning().withCause(e).log("Unexpected exception");
+                                  cause.addSuppressed(e);
+                                }
                               } else if (cacheMiss(response.status())) {
                                 outerF.setException(new CacheNotFoundException(digest));
                                 return;
@@ -606,8 +615,15 @@
                                 // If the error is due to an expired auth token and we can reset
                                 // the input stream, then try again.
                                 if (authTokenExpired(response) && reset(in)) {
-                                  refreshCredentials();
-                                  uploadAfterCredentialRefresh(upload, result);
+                                  try {
+                                    refreshCredentials();
+                                    uploadAfterCredentialRefresh(upload, result);
+                                  } catch (IOException e) {
+                                    result.setException(e);
+                                  } catch (RuntimeException e) {
+                                    logger.atWarning().withCause(e).log("Unexpected exception");
+                                    result.setException(e);
+                                  }
                                 } else {
                                   result.setException(cause);
                                 }