diff options
author | 2018-04-18 09:39:02 -0700 | |
---|---|---|
committer | 2018-04-18 09:40:44 -0700 | |
commit | 4803293f39b82ca2ed07c123e30c3f808f16e1a8 (patch) | |
tree | 728b8f85fea3a95bd5269a5673b06a19c9de36e0 /src | |
parent | 77a5be49a995ab413401f33dfc1523b50c1299c5 (diff) |
Handle InterruptedException thrown from @SkylarkCallable methods appropriately.
RELNOTES: None.
PiperOrigin-RevId: 193370435
Diffstat (limited to 'src')
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 |