aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe/PackageErrorFunction.java
diff options
context:
space:
mode:
authorGravatar Janak Ramakrishnan <janakr@google.com>2015-09-17 00:37:58 +0000
committerGravatar David Chen <dzc@google.com>2015-09-17 19:32:54 +0000
commit0a4c6e4608121eb1ef3f62dda5bddc8a9fed308d (patch)
treef214f6c39d8ffe9f9aeba6419b9a0243d71686d6 /src/main/java/com/google/devtools/build/lib/skyframe/PackageErrorFunction.java
parent44a7a6c10b621d0ef8aea40d93fa82591e67d555 (diff)
Stop throwing an exception if a Package was successfully created but contains errors. Instead, require callers to process the package and throw if they need to.
This allows us to avoid embedding a Package in an exception, which is icky. This also allows us to remove Package#containsTemporaryErrors. Most callers' changes are fairly straightforward. The exception is EnvironmentBackedRecursivePackageProvider, which cannot throw an exception of its own in case of a package with errors (because it doesn't do that in keep_going mode), but whose request for a package with errors *should* shut down the build in case of nokeep_going mode. To do this in Skyframe, we have a new PackageErrorFunction which is to be called only in this situation, and will unconditionally throw. EnvironmentBackedRecursivePackageProvider can then catch this exception and continue on as usual, except that the exception will shut down the thread pool in a nokeep_going build. -- MOS_MIGRATED_REVID=103247761
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/PackageErrorFunction.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PackageErrorFunction.java76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageErrorFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageErrorFunction.java
new file mode 100644
index 0000000000..c392c045d3
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageErrorFunction.java
@@ -0,0 +1,76 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.skyframe;
+
+import com.google.common.base.Preconditions;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
+import com.google.devtools.build.lib.packages.BuildFileNotFoundException;
+import com.google.devtools.build.lib.packages.NoSuchPackageException;
+import com.google.devtools.build.lib.packages.Package;
+import com.google.devtools.build.skyframe.SkyFunction;
+import com.google.devtools.build.skyframe.SkyFunctionException;
+import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
+import com.google.devtools.build.skyframe.SkyKey;
+import com.google.devtools.build.skyframe.SkyValue;
+
+import javax.annotation.Nullable;
+
+/**
+ * SkyFunction that throws a {@link BuildFileContainsErrorsException} for {@link Package} that
+ * loaded, but was in error. Must only be requested when a SkyFunction wishes to ignore the errors
+ * in a {@link Package} in keep_going mode, but to shut down the build in nokeep_going mode. Thus,
+ * this SkyFunction should only be requested when the corresponding {@link PackageFunction} has
+ * already been successfully called and the resulting Package contains an error.
+ *
+ * <p>This SkyFunction never returns a value, only throws a {@link BuildFileNotFoundException}, and
+ * should never return null, since all of its dependencies should already be present.
+ */
+public class PackageErrorFunction implements SkyFunction {
+ public static SkyKey key(PackageIdentifier packageIdentifier) {
+ return new SkyKey(SkyFunctions.PACKAGE_ERROR, packageIdentifier);
+ }
+
+ @Nullable
+ @Override
+ public SkyValue compute(SkyKey skyKey, Environment env) throws PackageErrorFunctionException {
+ PackageIdentifier packageIdentifier = (PackageIdentifier) skyKey.argument();
+ try {
+ SkyKey packageKey = PackageValue.key(packageIdentifier);
+ // Callers must have tried to load the package already and gotten the package successfully.
+ Package pkg =
+ ((PackageValue) env.getValueOrThrow(packageKey, NoSuchPackageException.class))
+ .getPackage();
+ Preconditions.checkState(pkg.containsErrors(), skyKey);
+ throw new PackageErrorFunctionException(
+ new BuildFileContainsErrorsException(packageIdentifier), Transience.PERSISTENT);
+ } catch (NoSuchPackageException e) {
+ throw new IllegalStateException(
+ "Function should not have been called on package with exception", e);
+ }
+ }
+
+ @Nullable
+ @Override
+ public String extractTag(SkyKey skyKey) {
+ return null;
+ }
+
+ private static class PackageErrorFunctionException extends SkyFunctionException {
+ public PackageErrorFunctionException(
+ BuildFileContainsErrorsException cause, Transience transience) {
+ super(cause, transience);
+ }
+ }
+}