aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar cparsons <cparsons@google.com>2018-04-18 09:39:02 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-04-18 09:40:44 -0700
commit4803293f39b82ca2ed07c123e30c3f808f16e1a8 (patch)
tree728b8f85fea3a95bd5269a5673b06a19c9de36e0 /src
parent77a5be49a995ab413401f33dfc1523b50c1299c5 (diff)
Handle InterruptedException thrown from @SkylarkCallable methods appropriately.
RELNOTES: None. PiperOrigin-RevId: 193370435
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java2
4 files changed, 18 insertions, 5 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java b/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java
index 16d0c642d6..c2cb348b37 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java
@@ -36,7 +36,16 @@ public class NativeInfo extends Info {
return values.get(name);
} else if (hasField(name)) {
MethodDescriptor methodDescriptor = FuncallExpression.getStructField(this.getClass(), name);
- return FuncallExpression.invokeStructField(methodDescriptor, name, this);
+ try {
+ return FuncallExpression.invokeStructField(methodDescriptor, name, this);
+ } catch (InterruptedException exception) {
+ // Struct fields on NativeInfo objects are supposed to behave well and not throw
+ // exceptions, as they should be logicless field accessors. If this occurs, it's
+ // indicative of a bad NativeInfo implementation.
+ throw new IllegalStateException(
+ String.format("Access of field %s was unexpectedly interrupted, but should be "
+ + "uninterruptible. This is indicative of a bad provider implementation.", name));
+ }
} else {
return null;
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
index 86313c132c..4a1507bbfa 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
@@ -82,7 +82,7 @@ public final class DotExpression extends Expression {
* Returns the field of the given name of the struct objValue, or null if no such field exists.
*/
public static Object eval(Object objValue, String name,
- Location loc, Environment env) throws EvalException {
+ Location loc, Environment env) throws EvalException, InterruptedException {
if (objValue instanceof SkylarkClassObject) {
try {
return ((SkylarkClassObject) objValue).getValue(name);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
index 1928fcec7f..dba8ffc92c 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
@@ -17,6 +17,7 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
@@ -353,13 +354,14 @@ public final class FuncallExpression extends Expression {
* @throws EvalException if there was an issue evaluating the method
*/
public static Object invokeStructField(
- MethodDescriptor methodDescriptor, String fieldName, Object obj) throws EvalException {
+ MethodDescriptor methodDescriptor, String fieldName, Object obj)
+ throws EvalException, InterruptedException {
Preconditions.checkArgument(methodDescriptor.getAnnotation().structField());
return callMethod(methodDescriptor, fieldName, obj, new Object[0], Location.BUILTIN, null);
}
static Object callMethod(MethodDescriptor methodDescriptor, String methodName, Object obj,
- Object[] args, Location loc, Environment env) throws EvalException {
+ Object[] args, Location loc, Environment env) throws EvalException, InterruptedException {
try {
Method method = methodDescriptor.getMethod();
if (obj == null && !Modifier.isStatic(method.getModifiers())) {
@@ -401,6 +403,8 @@ public final class FuncallExpression extends Expression {
if (e.getCause() instanceof FuncallException) {
throw new EvalException(loc, e.getCause().getMessage());
} else if (e.getCause() != null) {
+ Throwables.throwIfInstanceOf(e.getCause(), InterruptedException.class);
+
throw new EvalExceptionWithJavaCause(loc, e.getCause());
} else {
// This is unlikely to happen
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index a6b865e703..fe519b0a27 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -745,7 +745,7 @@ public class MethodLibrary {
@SuppressWarnings("unused")
public Object invoke(
Object obj, String name, Object defaultValue, Location loc, Environment env)
- throws EvalException {
+ throws EvalException, InterruptedException {
Object result = DotExpression.eval(obj, name, loc, env);
if (result == null) {
// 'Real' describes methods with structField() == false. Because DotExpression.eval