use of com.google.devtools.build.lib.actions.ActionExecutionException in project bazel by bazelbuild.
the class ArtifactFunction method createSimpleFileArtifactValue.
// Non-aggregating artifact -- should contain at most one piece of artifact data.
// data may be null if and only if artifact is a middleman artifact.
private static FileArtifactValue createSimpleFileArtifactValue(Artifact artifact, Action generatingAction, ActionExecutionValue actionValue, Environment env) throws ArtifactFunctionException {
FileArtifactValue value = actionValue.getArtifactValue(artifact);
if (value != null) {
return value;
}
// Middleman artifacts have no corresponding files, so their ArtifactValues should have already
// been constructed during execution of the action.
Preconditions.checkState(!artifact.isMiddlemanArtifact(), artifact);
FileValue data = Preconditions.checkNotNull(actionValue.getData(artifact), "%s %s", artifact, actionValue);
Preconditions.checkNotNull(data.getDigest(), "Digest should already have been calculated for %s (%s)", artifact, data);
try {
return FileArtifactValue.create(artifact, data);
} catch (IOException e) {
ActionExecutionException ex = new ActionExecutionException(e, generatingAction, /*catastrophe=*/
false);
env.getListener().handle(Event.error(ex.getLocation(), ex.getMessage()));
// This is a transient error since we did the work that led to the IOException.
throw new ArtifactFunctionException(ex, Transience.TRANSIENT);
}
}
use of com.google.devtools.build.lib.actions.ActionExecutionException in project bazel by bazelbuild.
the class ActionExecutionFunction method checkInputs.
/**
* Declare dependency on all known inputs of action. Throws exception if any are known to be
* missing. Some inputs may not yet be in the graph, in which case the builder should abort.
*/
private Pair<Map<Artifact, FileArtifactValue>, Map<Artifact, Collection<Artifact>>> checkInputs(Environment env, Action action, Map<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> inputDeps) throws ActionExecutionException {
int missingCount = 0;
int actionFailures = 0;
boolean catastrophe = false;
// Only populate input data if we have the input values, otherwise they'll just go unused.
// We still want to loop through the inputs to collect missing deps errors. During the
// evaluator "error bubbling", we may get one last chance at reporting errors even though
// some deps are still missing.
boolean populateInputData = !env.valuesMissing();
NestedSetBuilder<Cause> rootCauses = NestedSetBuilder.stableOrder();
Map<Artifact, FileArtifactValue> inputArtifactData = new HashMap<>(populateInputData ? inputDeps.size() : 0);
Map<Artifact, Collection<Artifact>> expandedArtifacts = new HashMap<>(populateInputData ? 128 : 0);
ActionExecutionException firstActionExecutionException = null;
for (Map.Entry<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> depsEntry : inputDeps.entrySet()) {
Artifact input = ArtifactSkyKey.artifact(depsEntry.getKey());
try {
SkyValue value = depsEntry.getValue().get();
if (populateInputData) {
if (value instanceof AggregatingArtifactValue) {
AggregatingArtifactValue aggregatingValue = (AggregatingArtifactValue) value;
for (Pair<Artifact, FileArtifactValue> entry : aggregatingValue.getInputs()) {
inputArtifactData.put(entry.first, entry.second);
}
// We have to cache the "digest" of the aggregating value itself,
// because the action cache checker may want it.
inputArtifactData.put(input, aggregatingValue.getSelfData());
ImmutableList.Builder<Artifact> expansionBuilder = ImmutableList.builder();
for (Pair<Artifact, FileArtifactValue> pair : aggregatingValue.getInputs()) {
expansionBuilder.add(pair.first);
}
expandedArtifacts.put(input, expansionBuilder.build());
} else if (value instanceof TreeArtifactValue) {
TreeArtifactValue treeValue = (TreeArtifactValue) value;
expandedArtifacts.put(input, ImmutableSet.<Artifact>copyOf(treeValue.getChildren()));
inputArtifactData.putAll(treeValue.getChildValues());
// Again, we cache the "digest" of the value for cache checking.
inputArtifactData.put(input, treeValue.getSelfData());
} else {
Preconditions.checkState(value instanceof FileArtifactValue, depsEntry);
inputArtifactData.put(input, (FileArtifactValue) value);
}
}
} catch (MissingInputFileException e) {
missingCount++;
if (input.getOwner() != null) {
rootCauses.add(new LabelCause(input.getOwner()));
}
} catch (ActionExecutionException e) {
actionFailures++;
if (firstActionExecutionException == null) {
firstActionExecutionException = e;
}
catastrophe = catastrophe || e.isCatastrophe();
rootCauses.addTransitive(e.getRootCauses());
}
}
// We need to rethrow first exception because it can contain useful error message
if (firstActionExecutionException != null) {
if (missingCount == 0 && actionFailures == 1) {
// having to copy the root causes to the upwards transitive closure.
throw firstActionExecutionException;
}
throw new ActionExecutionException(firstActionExecutionException.getMessage(), firstActionExecutionException.getCause(), action, rootCauses.build(), catastrophe, firstActionExecutionException.getExitCode());
}
if (missingCount > 0) {
for (Cause missingInput : rootCauses.build()) {
env.getListener().handle(Event.error(action.getOwner().getLocation(), String.format("%s: missing input file '%s'", action.getOwner().getLabel(), missingInput.getLabel())));
}
throw new ActionExecutionException(missingCount + " input file(s) do not exist", action, rootCauses.build(), /*catastrophe=*/
false);
}
return Pair.of(inputArtifactData, expandedArtifacts);
}
use of com.google.devtools.build.lib.actions.ActionExecutionException in project bazel by bazelbuild.
the class PopulateTreeArtifactActionTest method testTreeFileArtifactPathPrefixConflicts.
@Test
public void testTreeFileArtifactPathPrefixConflicts() throws Exception {
Action action = createPopulateTreeArtifactAction();
scratch.overwriteFile("archiveManifest.txt", "archive_members/conflict", "archive_members/conflict/1.class");
ActionExecutionContext executionContext = actionExecutionContext(new ArrayList<Artifact>());
try {
action.execute(executionContext);
fail("Artifact path prefix conflicts, expected exception");
} catch (ActionExecutionException e) {
// Expect ActionExecutionException
}
}
use of com.google.devtools.build.lib.actions.ActionExecutionException in project bazel by bazelbuild.
the class ExecutableSymlinkAction method execute.
@Override
public void execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException {
Path inputPath = actionExecutionContext.getExecutor().getExecRoot().getRelative(getInputPath());
try {
// Validate that input path is a file with the executable bit is set.
if (!inputPath.isFile()) {
throw new ActionExecutionException("'" + Iterables.getOnlyElement(getInputs()).prettyPrint() + "' is not a file", this, false);
}
if (!inputPath.isExecutable()) {
throw new ActionExecutionException("failed to create symbolic link '" + Iterables.getOnlyElement(getOutputs()).prettyPrint() + "': file '" + Iterables.getOnlyElement(getInputs()).prettyPrint() + "' is not executable", this, false);
}
} catch (IOException e) {
throw new ActionExecutionException("failed to create symbolic link '" + Iterables.getOnlyElement(getOutputs()).prettyPrint() + "' to the '" + Iterables.getOnlyElement(getInputs()).prettyPrint() + "' due to I/O error: " + e.getMessage(), e, this, false);
}
super.execute(actionExecutionContext);
}
use of com.google.devtools.build.lib.actions.ActionExecutionException in project bazel by bazelbuild.
the class PopulateTreeArtifactAction method execute.
@Override
public void execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException {
Executor executor = actionExecutionContext.getExecutor();
Spawn spawn;
// Create a spawn to unzip the archive file into the output TreeArtifact.
try {
spawn = createSpawn();
} catch (IOException e) {
throw new ActionExecutionException(e, this, false);
} catch (IllegalManifestFileException e) {
throw new ActionExecutionException(e, this, true);
}
// case we just return without generating anything under the output TreeArtifact.
if (spawn.getOutputFiles().isEmpty()) {
return;
}
// Check spawn output TreeFileArtifact conflicts.
try {
checkOutputConflicts(spawn.getOutputFiles());
} catch (ArtifactPrefixConflictException e) {
throw new ActionExecutionException(e, this, true);
}
// Create parent directories for the output TreeFileArtifacts.
try {
for (ActionInput fileEntry : spawn.getOutputFiles()) {
FileSystemUtils.createDirectoryAndParents(((Artifact) fileEntry).getPath().getParentDirectory());
}
} catch (IOException e) {
throw new ActionExecutionException(e, this, false);
}
// Execute the spawn.
try {
getContext(executor).exec(spawn, actionExecutionContext);
} catch (ExecException e) {
throw e.toActionExecutionException(getMnemonic() + " action failed for target: " + getOwner().getLabel(), executor.getVerboseFailures(), this);
}
// Populate the output TreeArtifact with the Spawn output TreeFileArtifacts.
for (ActionInput fileEntry : spawn.getOutputFiles()) {
actionExecutionContext.getMetadataHandler().addExpandedTreeOutput((TreeFileArtifact) fileEntry);
}
}
Aggregations