Skip to content

Commit

Permalink
[7.4.0] Improve user-visible error message when an IOException occurs…
Browse files Browse the repository at this point in the history
… while copying sandbox inputs/outputs. (#23381)

Also wrap it in an EnvironmentalExecException, as it seems more
appropriate than a UserExecException; introduce separate failure codes
while at it.

(We should probably rethink whether SpawnRunner#exec should even be
allowed to return a naked IOException, but that's a much larger change.)

Fixes #23283.

PiperOrigin-RevId: 665790329
Change-Id: Ibf12481c19d155dc3d4f95e21df3e8ee305f3512

Commit
f5df0e7

Co-authored-by: Googler <tjgq@google.com>
  • Loading branch information
bazel-io and tjgq authored Aug 22, 2024
1 parent 60cbce1 commit 048f843
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.ActionExecutionMetadata;
import com.google.devtools.build.lib.actions.EnvironmentalExecException;
import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.actions.ForbiddenActionInputException;
import com.google.devtools.build.lib.actions.ResourceManager;
Expand Down Expand Up @@ -139,10 +140,15 @@ protected abstract SandboxedSpawn prepareSpawn(Spawn spawn, SpawnExecutionContex

private SpawnResult runSpawn(
Spawn originalSpawn, SandboxedSpawn sandbox, SpawnExecutionContext context)
throws IOException, ForbiddenActionInputException, InterruptedException {
throws ExecException, ForbiddenActionInputException, IOException, InterruptedException {
try {
try (SilentCloseable c = Profiler.instance().profile("sandbox.createFileSystem")) {
sandbox.createFileSystem();
} catch (IOException e) {
FailureDetail failureDetail =
SandboxHelpers.createFailureDetail(
"Could not copy inputs into sandbox", Code.COPY_INPUTS_IO_EXCEPTION);
throw new EnvironmentalExecException(e, failureDetail);
}
SpawnResult result;
try (SilentCloseable c = Profiler.instance().profile("subprocess.run")) {
Expand All @@ -160,7 +166,10 @@ private SpawnResult runSpawn(
// We copy the outputs even when the command failed.
sandbox.copyOutputs(execRoot);
} catch (IOException e) {
throw new IOException("Could not move output artifacts from sandboxed execution", e);
FailureDetail failureDetail =
SandboxHelpers.createFailureDetail(
"Could not copy outputs from sandbox", Code.COPY_OUTPUTS_IO_EXCEPTION);
throw new EnvironmentalExecException(e, failureDetail);
}
return result;
} finally {
Expand Down
2 changes: 2 additions & 0 deletions src/main/protobuf/failure_details.proto
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,8 @@ message Sandbox {
MOUNT_TARGET_DOES_NOT_EXIST = 9 [(metadata) = { exit_code: 1 }];
SUBPROCESS_START_FAILED = 10 [(metadata) = { exit_code: 36 }];
FORBIDDEN_INPUT = 11 [(metadata) = { exit_code: 1 }];
COPY_INPUTS_IO_EXCEPTION = 12 [(metadata) = { exit_code: 36 }];
COPY_OUTPUTS_IO_EXCEPTION = 13 [(metadata) = { exit_code: 36 }];
}

Code code = 1;
Expand Down
6 changes: 3 additions & 3 deletions src/test/shell/integration/sandboxing_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ EOF
expect_not_log "Executing genrule //:test failed: linux-sandbox failed: error executing command"

# This is the error message telling us that some output artifacts couldn't be copied.
expect_log "Could not move output artifacts from sandboxed execution"
expect_log "Could not copy outputs from sandbox:.*readonlydir/output.txt (Permission denied)"

# The build fails, because the action didn't generate its output artifact.
expect_log "ERROR:.*Executing genrule //:test failed"
Expand All @@ -689,10 +689,10 @@ EOF

# This is the error message printed by the EventHandler telling us that some
# output artifacts couldn't be copied.
expect_log "Could not move output artifacts from sandboxed execution"
expect_log "Could not copy outputs from sandbox:.*readonlydir/output.txt (Permission denied)"

# This is the UserExecException telling us that the build failed.
expect_log "Executing genrule //:test failed:"
expect_log "ERROR:.*Executing genrule //:test failed:"
}

function test_read_non_hermetic_tmp {
Expand Down

0 comments on commit 048f843

Please sign in to comment.