diff options
author | 2017-09-01 13:14:19 +0200 | |
---|---|---|
committer | 2017-09-01 15:28:54 +0200 | |
commit | a659135bb1dd5a3e7000a0fb0979c235a54f6190 (patch) | |
tree | 563cf2efbacf97267fbd72de9fa31d651e5ba24c /src/main/java | |
parent | 621c096ff76b898118f2033b3ac974d73e137ede (diff) |
remote: Return exit code 34 for remote caching/execution errors.
For any errors that are due to failures in the remote caching /
execution layers Bazel now returns exit code 34 (ExitCode.REMOTE_ERROR).
This includes errors where the remote cache / executor is unreachable or
crashes. It does not include errors if the test / build failure is due
to user errors i.e. compilation or test failures.
PiperOrigin-RevId: 167259236
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/exec/SpawnResult.java | 6 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnRunner.java | 62 |
2 files changed, 38 insertions, 30 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/exec/SpawnResult.java b/src/main/java/com/google/devtools/build/lib/exec/SpawnResult.java index b3a03839d3..d2d3ee8ad6 100644 --- a/src/main/java/com/google/devtools/build/lib/exec/SpawnResult.java +++ b/src/main/java/com/google/devtools/build/lib/exec/SpawnResult.java @@ -94,6 +94,12 @@ public interface SpawnResult { REMOTE_EXECUTOR_OVERLOADED, /** + * The result of the remotely executed Spawn could not be retrieved due to errors in the remote + * caching layer. + */ + REMOTE_CACHE_FAILED, + + /** * The remote execution system did not allow the request due to missing authorization or * authentication. */ diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnRunner.java index 69b751cbda..bd53704b3d 100644 --- a/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnRunner.java +++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteSpawnRunner.java @@ -27,12 +27,14 @@ import com.google.devtools.build.lib.actions.cache.VirtualActionInput; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.Reporter; +import com.google.devtools.build.lib.exec.SpawnExecException; import com.google.devtools.build.lib.exec.SpawnInputExpander; import com.google.devtools.build.lib.exec.SpawnResult; import com.google.devtools.build.lib.exec.SpawnResult.Status; import com.google.devtools.build.lib.exec.SpawnRunner; import com.google.devtools.build.lib.remote.Digests.ActionKey; import com.google.devtools.build.lib.remote.TreeNodeRepository.TreeNode; +import com.google.devtools.build.lib.util.ExitCode; import com.google.devtools.build.lib.util.io.FileOutErr; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; @@ -209,40 +211,40 @@ class RemoteSpawnRunner implements SpawnRunner { if (options.remoteLocalFallback) { return execLocally(spawn, policy, inputMap, uploadLocalResults, remoteCache, actionKey); } - if (cause instanceof TimeoutException) { - return handleTimeout(policy.getFileOutErr()); - } - throw new EnvironmentalExecException(errorMessage(cause), cause, true); - } - - private SpawnResult handleTimeout(FileOutErr outErr) throws IOException { - // TODO(buchgr): Once the remote execution protocol allows it, also provide stdout/stderr - // from the action that timed out. - try (OutputStream out = outErr.getOutputStream()) { - // This is a hack to ensure that the test.log file gets created, as else the action - // will complain that one of its outputs has not been created. - String msg = "Log output for timeouts is not yet supported in remote execution."; - out.write(msg.getBytes(StandardCharsets.UTF_8)); - out.flush(); - } - return new SpawnResult.Builder().setStatus(Status.TIMEOUT).build(); + return handleError(cause, policy.getFileOutErr()); } - private String errorMessage(IOException e) { - String message = ""; - if (e instanceof RetryException - && ((RetryException) e).causedByStatusCode(Code.UNAVAILABLE)) { - message = "The remote executor/cache is unavailable"; - } else if (e instanceof CacheNotFoundException) { - message = "Failed to download from remote cache"; + private SpawnResult handleError(IOException cause, FileOutErr outErr) throws IOException, + ExecException { + final Status status; + if (cause instanceof TimeoutException) { + status = Status.TIMEOUT; + // TODO(buchgr): Once the remote execution protocol allows it, also provide stdout/stderr + // from the action that timed out. + try (OutputStream out = outErr.getOutputStream()) { + // This is a hack to ensure that the test.log file gets created, as else the action + // will complain that one of its outputs has not been created. + String msg = "Log output for timeouts is not yet supported in remote execution."; + out.write(msg.getBytes(StandardCharsets.UTF_8)); + out.flush(); + } + return new SpawnResult.Builder().setStatus(status).build(); + } else if (cause instanceof RetryException + && ((RetryException) cause).causedByStatusCode(Code.UNAVAILABLE)) { + status = Status.CONNECTION_FAILED; + } else if (cause instanceof CacheNotFoundException) { + status = Status.REMOTE_CACHE_FAILED; } else { - message = "Error in remote cache/executor"; - } - // TODO(olaola): reuse the ErrorMessage class for these errors. - if (verboseFailures) { - message += "\n" + Throwables.getStackTraceAsString(e); + status = Status.EXECUTION_FAILED; } - return message; + throw new SpawnExecException( + Throwables.getStackTraceAsString(cause), + new SpawnResult + .Builder() + .setExitCode(ExitCode.REMOTE_ERROR.getNumericExitCode()) + .setStatus(status) + .build(), + /*catastrophic=*/true); } static Action buildAction( |