Refactor DependencyResolver to collect and return loading errors.
This should never be triggered in production, where we always run a loading
phase first and only analyze targets that load successfully. I.e., this is
just plumbing which will be hooked up in a subsequent change.
--
MOS_MIGRATED_REVID=113258593
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
index 2d0549b..4917d28 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
@@ -26,7 +26,9 @@
import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.packages.Attribute;
@@ -105,6 +107,7 @@
throws AspectFunctionException, InterruptedException {
SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
NestedSetBuilder<Package> transitivePackages = NestedSetBuilder.stableOrder();
+ NestedSetBuilder<Label> transitiveRootCauses = NestedSetBuilder.stableOrder();
AspectKey key = (AspectKey) skyKey.argument();
ConfiguredAspectFactory aspectFactory;
if (key.getAspectClass() instanceof NativeAspectClass<?>) {
@@ -152,9 +155,15 @@
"aspects must be attached to rules"));
}
- final ConfiguredTargetValue configuredTargetValue =
- (ConfiguredTargetValue)
- env.getValue(ConfiguredTargetValue.key(key.getLabel(), key.getConfiguration()));
+ final ConfiguredTargetValue configuredTargetValue;
+ try {
+ configuredTargetValue =
+ (ConfiguredTargetValue) env.getValueOrThrow(
+ ConfiguredTargetValue.key(key.getLabel(), key.getConfiguration()),
+ ConfiguredValueCreationException.class);
+ } catch (ConfiguredValueCreationException e) {
+ throw new AspectFunctionException(new AspectCreationException(e.getRootCauses()));
+ }
if (configuredTargetValue == null) {
// TODO(bazel-team): remove this check when top-level targets also use dynamic configurations.
// Right now the key configuration may be dynamic while the original target's configuration
@@ -175,7 +184,7 @@
try {
// Get the configuration targets that trigger this rule's configurable attributes.
Set<ConfigMatchingProvider> configConditions = ConfiguredTargetFunction.getConfigConditions(
- target, env, resolver, ctgValue, transitivePackages);
+ target, env, resolver, ctgValue, transitivePackages, transitiveRootCauses);
if (configConditions == null) {
// Those targets haven't yet been resolved.
return null;
@@ -190,7 +199,15 @@
configConditions,
ruleClassProvider,
view.getHostConfiguration(ctgValue.getConfiguration()),
- transitivePackages);
+ transitivePackages,
+ transitiveRootCauses);
+ if (depValueMap == null) {
+ return null;
+ }
+ if (!transitiveRootCauses.isEmpty()) {
+ throw new AspectFunctionException(
+ new AspectCreationException("Loading failed", transitiveRootCauses.build()));
+ }
return createAspect(
env,
@@ -282,6 +299,9 @@
* An exception indicating that there was a problem creating an aspect.
*/
public static final class AspectCreationException extends Exception {
+ /** Targets in the transitive closure that failed to load. May be empty. */
+ private final NestedSet<Label> loadingRootCauses;
+
/**
* The target for which analysis failed, if any. We can't represent aspects with labels, so if
* the aspect analysis fails, this will be {@code null}.
@@ -290,11 +310,26 @@
public AspectCreationException(String message, Label analysisRootCause) {
super(message);
+ this.loadingRootCauses = NestedSetBuilder.<Label>emptySet(Order.STABLE_ORDER);
this.analysisRootCause = analysisRootCause;
}
+ public AspectCreationException(String message, NestedSet<Label> loadingRootCauses) {
+ super(message);
+ this.loadingRootCauses = loadingRootCauses;
+ this.analysisRootCause = null;
+ }
+
+ public AspectCreationException(NestedSet<Label> loadingRootCauses) {
+ this("Loading failed", loadingRootCauses);
+ }
+
public AspectCreationException(String message) {
- this(message, null);
+ this(message, (Label) null);
+ }
+
+ public NestedSet<Label> getRootCauses() {
+ return loadingRootCauses;
}
@Nullable public Label getAnalysisRootCause() {