Skip to content

Commit 6102d33

Browse files
ShreeM01tjgq
andauthored
Propagate the error message when a credential helper fails. (#16030)
Closes #16012. PiperOrigin-RevId: 464732834 Change-Id: If51ce914098ff17ffe23fa4614947e7f4a5088dc Co-authored-by: Tiago Quelhas <[email protected]>
1 parent 0109031 commit 6102d33

File tree

5 files changed

+61
-17
lines changed

5 files changed

+61
-17
lines changed

src/main/java/com/google/devtools/build/lib/authandtls/credentialhelper/CredentialHelper.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,15 @@ public GetCredentialsResponse getCredentials(CredentialHelperEnvironment environ
7777

7878
process.waitFor();
7979
if (process.timedout()) {
80-
throw new IOException(
80+
throw new CredentialHelperException(
8181
String.format(
8282
Locale.US,
8383
"Failed to get credentials for '%s' from helper '%s': process timed out",
8484
uri,
8585
path));
8686
}
8787
if (process.exitValue() != 0) {
88-
throw new IOException(
88+
throw new CredentialHelperException(
8989
String.format(
9090
Locale.US,
9191
"Failed to get credentials for '%s' from helper '%s': process exited with code %d."
@@ -99,7 +99,7 @@ public GetCredentialsResponse getCredentials(CredentialHelperEnvironment environ
9999
try {
100100
GetCredentialsResponse response = GSON.fromJson(stdout, GetCredentialsResponse.class);
101101
if (response == null) {
102-
throw new IOException(
102+
throw new CredentialHelperException(
103103
String.format(
104104
Locale.US,
105105
"Failed to get credentials for '%s' from helper '%s': process exited without"
@@ -110,7 +110,7 @@ public GetCredentialsResponse getCredentials(CredentialHelperEnvironment environ
110110
}
111111
return response;
112112
} catch (JsonSyntaxException e) {
113-
throw new IOException(
113+
throw new CredentialHelperException(
114114
String.format(
115115
Locale.US,
116116
"Failed to get credentials for '%s' from helper '%s': error parsing output. stderr:"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2022 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.devtools.build.lib.authandtls.credentialhelper;
16+
17+
import java.io.IOException;
18+
19+
/** An {@link Exception} thrown while invoking a credential helper. */
20+
public class CredentialHelperException extends IOException {
21+
public CredentialHelperException(String message) {
22+
super(message);
23+
}
24+
25+
public CredentialHelperException(String message, Throwable cause) {
26+
super(message, cause);
27+
}
28+
}

src/main/java/com/google/devtools/build/lib/remote/util/BUILD

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ java_library(
1919
"//src/main/java/com/google/devtools/build/lib/actions:execution_requirements",
2020
"//src/main/java/com/google/devtools/build/lib/analysis:blaze_version_info",
2121
"//src/main/java/com/google/devtools/build/lib/authandtls",
22+
"//src/main/java/com/google/devtools/build/lib/authandtls/credentialhelper",
2223
"//src/main/java/com/google/devtools/build/lib/cmdline",
2324
"//src/main/java/com/google/devtools/build/lib/remote:ExecutionStatusException",
2425
"//src/main/java/com/google/devtools/build/lib/remote/common",

src/main/java/com/google/devtools/build/lib/remote/util/Utils.java

+16-3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.google.devtools.build.lib.actions.SpawnResult;
4040
import com.google.devtools.build.lib.actions.Spawns;
4141
import com.google.devtools.build.lib.authandtls.CallCredentialsProvider;
42+
import com.google.devtools.build.lib.authandtls.credentialhelper.CredentialHelperException;
4243
import com.google.devtools.build.lib.remote.ExecutionStatusException;
4344
import com.google.devtools.build.lib.remote.common.CacheNotFoundException;
4445
import com.google.devtools.build.lib.remote.common.OutputDigestMismatchException;
@@ -367,6 +368,7 @@ private static String executionStatusExceptionErrorMessage(ExecutionStatusExcept
367368
public static String grpcAwareErrorMessage(IOException e) {
368369
io.grpc.Status errStatus = io.grpc.Status.fromThrowable(e);
369370
if (e.getCause() instanceof ExecutionStatusException) {
371+
// Display error message returned by the remote service.
370372
try {
371373
return "Remote Execution Failure:\n"
372374
+ executionStatusExceptionErrorMessage((ExecutionStatusException) e.getCause());
@@ -378,9 +380,20 @@ public static String grpcAwareErrorMessage(IOException e) {
378380
}
379381
}
380382
if (!errStatus.getCode().equals(io.grpc.Status.UNKNOWN.getCode())) {
381-
// If the error originated in the gRPC library then display it as "STATUS: error message"
382-
// to the user
383-
return String.format("%s: %s", errStatus.getCode().name(), errStatus.getDescription());
383+
// Display error message returned by the gRPC library, prefixed by the status code.
384+
StringBuilder sb = new StringBuilder();
385+
sb.append(errStatus.getCode().name());
386+
sb.append(": ");
387+
sb.append(errStatus.getDescription());
388+
// If the error originated from a credential helper, print additional debugging information.
389+
for (Throwable t = errStatus.getCause(); t != null; t = t.getCause()) {
390+
if (t instanceof CredentialHelperException) {
391+
sb.append(": ");
392+
sb.append(t.getMessage());
393+
break;
394+
}
395+
}
396+
return sb.toString();
384397
}
385398
return e.getMessage();
386399
}

src/test/java/com/google/devtools/build/lib/authandtls/credentialhelper/CredentialHelperTest.java

+12-10
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import com.google.devtools.build.lib.vfs.PathFragment;
2929
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
3030
import com.google.devtools.build.runfiles.Runfiles;
31-
import java.io.IOException;
3231
import java.net.URI;
3332
import java.time.Duration;
3433
import org.junit.Test;
@@ -95,18 +94,20 @@ public void knownUriWithMultipleHeaders() throws Exception {
9594

9695
@Test
9796
public void unknownUri() {
98-
IOException ioException =
97+
CredentialHelperException e =
9998
assertThrows(
100-
IOException.class, () -> getCredentialsFromHelper("https://unknown.example.com"));
101-
assertThat(ioException).hasMessageThat().contains("Unknown uri 'https://unknown.example.com'");
99+
CredentialHelperException.class,
100+
() -> getCredentialsFromHelper("https://unknown.example.com"));
101+
assertThat(e).hasMessageThat().contains("Unknown uri 'https://unknown.example.com'");
102102
}
103103

104104
@Test
105105
public void credentialHelperOutputsNothing() throws Exception {
106-
IOException ioException =
106+
CredentialHelperException e =
107107
assertThrows(
108-
IOException.class, () -> getCredentialsFromHelper("https://printnothing.example.com"));
109-
assertThat(ioException).hasMessageThat().contains("exited without output");
108+
CredentialHelperException.class,
109+
() -> getCredentialsFromHelper("https://printnothing.example.com"));
110+
assertThat(e).hasMessageThat().contains("exited without output");
110111
}
111112

112113
@Test
@@ -135,9 +136,10 @@ public void helperGetEnvironment() throws Exception {
135136

136137
@Test
137138
public void helperTimeout() throws Exception {
138-
IOException ioException =
139+
CredentialHelperException e =
139140
assertThrows(
140-
IOException.class, () -> getCredentialsFromHelper("https://timeout.example.com"));
141-
assertThat(ioException).hasMessageThat().contains("process timed out");
141+
CredentialHelperException.class,
142+
() -> getCredentialsFromHelper("https://timeout.example.com"));
143+
assertThat(e).hasMessageThat().contains("process timed out");
142144
}
143145
}

0 commit comments

Comments
 (0)