Wrap FindMissingBlobs exceptions in IOException
Consistent with #7860, present an IOException with context to ensure
fallback if configured, rather than an unhandled RuntimeException and
bazel crash, when issuing FindMissingBlobs requests.
Closes #10663.
PiperOrigin-RevId: 295957563
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 1c07c87..1750526 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
@@ -191,16 +191,30 @@
getMissingDigestCalls.add(getMissingDigests(requestBuilder.build()));
}
- return Futures.whenAllSucceed(getMissingDigestCalls)
- .call(
- () -> {
- ImmutableSet.Builder<Digest> result = ImmutableSet.builder();
- for (ListenableFuture<FindMissingBlobsResponse> callFuture : getMissingDigestCalls) {
- result.addAll(callFuture.get().getMissingBlobDigestsList());
- }
- return result.build();
- },
- MoreExecutors.directExecutor());
+ ListenableFuture<ImmutableSet<Digest>> success =
+ Futures.whenAllSucceed(getMissingDigestCalls)
+ .call(
+ () -> {
+ ImmutableSet.Builder<Digest> result = ImmutableSet.builder();
+ for (ListenableFuture<FindMissingBlobsResponse> callFuture :
+ getMissingDigestCalls) {
+ result.addAll(callFuture.get().getMissingBlobDigestsList());
+ }
+ return result.build();
+ },
+ MoreExecutors.directExecutor());
+ return Futures.catchingAsync(
+ success,
+ RuntimeException.class,
+ (e) ->
+ Futures.immediateFailedFuture(
+ new IOException(
+ String.format(
+ "findMissingBlobs(%d) for %s",
+ requestBuilder.getBlobDigestsCount(),
+ TracingMetadataUtils.fromCurrentContext().getActionId()),
+ e)),
+ MoreExecutors.directExecutor());
}
private ListenableFuture<FindMissingBlobsResponse> getMissingDigests(