Move analysis root cause tracking to the ConfiguredTargetFunction.

The main remaining problem with interleaved loading and analysis is error
handling. When interleaving, we don't run a real loading phase anymore, and
loading errors can occur during the analysis phase, and need to be handled
there.

The plan is to have ConfiguredTargetFunction throw a
ConfiguredValueCreationException with a list of all loading root causes, which
requires that we also catch ConfiguredValueCreationException here, which in
turn breaks analysis root cause handling, as that is currently relying on
Skyframe root cause tracking.

Moving analysis root cause handling into CTFunction makes it possible to
subsequently also implement loading root cause handling here. This is also
necessary if we want to have complete root cause handling in the general case:
a target may have any number (and combination) of loading and analysis root
causes at the same time.

For now, we only pass a single analysis root cause, which mirrors the current
Skyframe-based implementation.

--
MOS_MIGRATED_REVID=112930871
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 032434d..dca5c79 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
@@ -24,6 +24,7 @@
 import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 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.NestedSetBuilder;
 import com.google.devtools.build.lib.events.StoredEventHandler;
@@ -39,6 +40,7 @@
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.rules.SkylarkRuleClassFunctions.SkylarkAspect;
 import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey;
+import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ConfiguredValueCreationException;
 import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.DependencyEvaluationException;
 import com.google.devtools.build.lib.skyframe.SkyframeExecutor.BuildViewProvider;
 import com.google.devtools.build.lib.skyframe.SkylarkImportLookupFunction.SkylarkImportFailedException;
@@ -195,7 +197,16 @@
           depValueMap,
           transitivePackages);
     } catch (DependencyEvaluationException e) {
-      throw new AspectFunctionException(e.getRootCauseSkyKey(), e.getCause());
+      if (e.getCause() instanceof ConfiguredValueCreationException) {
+        ConfiguredValueCreationException cause = (ConfiguredValueCreationException) e.getCause();
+        throw new AspectFunctionException(new AspectCreationException(
+            cause.getMessage(), cause.getAnalysisRootCause()));
+      } else {
+        // Cast to InvalidConfigurationException as a consistency check. If you add any
+        // DependencyEvaluationException constructors, you may need to change this code, too.
+        InvalidConfigurationException cause = (InvalidConfigurationException) e.getCause();
+        throw new AspectFunctionException(new AspectCreationException(cause.getMessage()));
+      }
     } catch (AspectCreationException e) {
       throw new AspectFunctionException(e);
     }
@@ -267,8 +278,23 @@
    * An exception indicating that there was a problem creating an aspect.
    */
   public static final class AspectCreationException extends Exception {
-    public AspectCreationException(String message) {
+    /**
+     * 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}.
+     */
+    @Nullable private final Label analysisRootCause;
+
+    public AspectCreationException(String message, Label analysisRootCause) {
       super(message);
+      this.analysisRootCause = analysisRootCause;
+    }
+
+    public AspectCreationException(String message) {
+      this(message, null);
+    }
+
+    @Nullable public Label getAnalysisRootCause() {
+      return analysisRootCause;
     }
   }