From 3d9942ebee409241045adfd5a69d3d8b5c9bbd93 Mon Sep 17 00:00:00 2001 From: Sokwhan Huh Date: Fri, 24 Jan 2025 18:26:40 -0800 Subject: [PATCH] Remove InterpreterException PiperOrigin-RevId: 719502577 --- .../main/java/dev/cel/runtime/Activation.java | 2 +- .../src/main/java/dev/cel/runtime/BUILD.bazel | 13 +- .../CelEvaluationExceptionBuilder.java | 10 +- .../cel/runtime/CelLateFunctionBindings.java | 11 +- .../main/java/dev/cel/runtime/CelRuntime.java | 53 ++---- .../dev/cel/runtime/CelRuntimeLegacyImpl.java | 13 +- .../dev/cel/runtime/CelStandardFunctions.java | 167 ++++++------------ .../dev/cel/runtime/DefaultDispatcher.java | 10 +- .../dev/cel/runtime/DefaultInterpreter.java | 123 +++++++------ .../dev/cel/runtime/FunctionOverload.java | 7 +- .../dev/cel/runtime/FunctionResolver.java | 5 +- .../java/dev/cel/runtime/Interpretable.java | 7 +- .../dev/cel/runtime/InterpreterException.java | 122 ------------- .../java/dev/cel/runtime/InterpreterUtil.java | 10 +- .../runtime/UnknownTrackingInterpretable.java | 2 +- .../runtime/CelLateFunctionBindingsTest.java | 24 ++- .../cel/runtime/DefaultDispatcherTest.java | 4 +- 17 files changed, 187 insertions(+), 396 deletions(-) delete mode 100644 runtime/src/main/java/dev/cel/runtime/InterpreterException.java diff --git a/runtime/src/main/java/dev/cel/runtime/Activation.java b/runtime/src/main/java/dev/cel/runtime/Activation.java index b7757e77..d78ac741 100644 --- a/runtime/src/main/java/dev/cel/runtime/Activation.java +++ b/runtime/src/main/java/dev/cel/runtime/Activation.java @@ -171,7 +171,7 @@ public static Activation fromProto(Message message, CelOptions celOptions) { } catch (IllegalArgumentException e) { variables.put( field.getName(), - new InterpreterException.Builder( + CelEvaluationExceptionBuilder.newBuilder( "illegal field value. field=%s, value=%s", field.getName(), fieldValue) .setCause(e) .build()); diff --git a/runtime/src/main/java/dev/cel/runtime/BUILD.bazel b/runtime/src/main/java/dev/cel/runtime/BUILD.bazel index 2d0f7007..03a63dd7 100644 --- a/runtime/src/main/java/dev/cel/runtime/BUILD.bazel +++ b/runtime/src/main/java/dev/cel/runtime/BUILD.bazel @@ -12,7 +12,6 @@ BASE_SOURCES = [ "DefaultMetadata.java", "FunctionResolver.java", "FunctionOverload.java", - "InterpreterException.java", "MessageProvider.java", "Registrar.java", "ResolvedOverload.java", @@ -55,18 +54,15 @@ java_library( tags = [ ], deps = [ + ":evaluation_exception", ":metadata", "//:auto_value", "//common", - "//common:error_codes", - "//common:runtime_exception", "//common/annotations", - "//common/internal:safe_string_formatter", "@maven//:com_google_code_findbugs_annotations", "@maven//:com_google_errorprone_error_prone_annotations", "@maven//:com_google_guava_guava", "@maven//:com_google_protobuf_protobuf_java", - "@maven//:org_jspecify_jspecify", ], ) @@ -80,6 +76,8 @@ java_library( deps = [ ":base", ":cel_type_resolver", + ":evaluation_exception", + ":evaluation_exception_builder", ":evaluation_listener", ":metadata", ":runtime_helper", @@ -197,7 +195,6 @@ java_library( ], deps = [ ":evaluation_exception", - ":evaluation_exception_builder", ":evaluation_listener", ":runtime_helper", ":runtime_type_provider_legacy", @@ -206,12 +203,14 @@ java_library( "//common", "//common:error_codes", "//common:options", + "//common:runtime_exception", "//common/annotations", "//common/internal:cel_descriptor_pools", "//common/internal:comparison_functions", "//common/internal:default_message_factory", "//common/internal:dynamic_proto", "//common/internal:proto_message_factory", + "//common/internal:safe_string_formatter", "//common/types:cel_types", "//common/values:cel_value_provider", "//common/values:proto_message_value_provider", @@ -295,9 +294,9 @@ java_library( tags = [ ], deps = [ - ":base", ":unknown_attributes", "//common/annotations", + "//runtime", "@maven//:com_google_errorprone_error_prone_annotations", "@maven//:org_jspecify_jspecify", ], diff --git a/runtime/src/main/java/dev/cel/runtime/CelEvaluationExceptionBuilder.java b/runtime/src/main/java/dev/cel/runtime/CelEvaluationExceptionBuilder.java index b02500c8..7ee06295 100644 --- a/runtime/src/main/java/dev/cel/runtime/CelEvaluationExceptionBuilder.java +++ b/runtime/src/main/java/dev/cel/runtime/CelEvaluationExceptionBuilder.java @@ -57,12 +57,10 @@ public CelEvaluationExceptionBuilder setMetadata(Metadata metadata, long exprId) */ @Internal public CelEvaluationException build() { - // TODO: Temporary until InterpreterException removal is complete - if (!message.startsWith("evaluation error")) { - message = SafeStringFormatter.format("evaluation error%s: %s", errorLocation, message); - } - - return new CelEvaluationException(message, cause, errorCode); + return new CelEvaluationException( + SafeStringFormatter.format("evaluation error%s: %s", errorLocation, message), + cause, + errorCode); } /** diff --git a/runtime/src/main/java/dev/cel/runtime/CelLateFunctionBindings.java b/runtime/src/main/java/dev/cel/runtime/CelLateFunctionBindings.java index 0fea43b0..12595016 100644 --- a/runtime/src/main/java/dev/cel/runtime/CelLateFunctionBindings.java +++ b/runtime/src/main/java/dev/cel/runtime/CelLateFunctionBindings.java @@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableMap; import com.google.errorprone.annotations.Immutable; -import dev.cel.common.CelException; import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -38,7 +37,7 @@ private CelLateFunctionBindings(ImmutableMap functions @Override public Optional findOverload( - String functionName, List overloadIds, Object[] args) throws CelException { + String functionName, List overloadIds, Object[] args) throws CelEvaluationException { return DefaultDispatcher.findOverload(functionName, overloadIds, functions, args); } @@ -59,12 +58,6 @@ private static ResolvedOverload createResolvedOverload(CelRuntime.CelFunctionBin return CelResolvedOverload.of( binding.getOverloadId(), binding.getArgTypes(), - (args) -> { - try { - return binding.getDefinition().apply(args); - } catch (CelException e) { - throw InterpreterException.wrapOrThrow(e); - } - }); + (args) -> binding.getDefinition().apply(args)); } } diff --git a/runtime/src/main/java/dev/cel/runtime/CelRuntime.java b/runtime/src/main/java/dev/cel/runtime/CelRuntime.java index 2c976c9e..f61dc98a 100644 --- a/runtime/src/main/java/dev/cel/runtime/CelRuntime.java +++ b/runtime/src/main/java/dev/cel/runtime/CelRuntime.java @@ -18,7 +18,6 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.errorprone.annotations.CanIgnoreReturnValue; -import com.google.errorprone.annotations.CheckReturnValue; import com.google.errorprone.annotations.Immutable; import javax.annotation.concurrent.ThreadSafe; import com.google.protobuf.Message; @@ -192,30 +191,26 @@ private Object evalInternal( Optional lateBoundFunctionResolver, CelEvaluationListener listener) throws CelEvaluationException { - try { - Interpretable impl = getInterpretable(); - if (getOptions().enableUnknownTracking()) { - Preconditions.checkState( - impl instanceof UnknownTrackingInterpretable, - "Environment misconfigured. Requested unknown tracking without a compatible" - + " implementation."); - - UnknownTrackingInterpretable interpreter = (UnknownTrackingInterpretable) impl; - return interpreter.evalTrackingUnknowns( - RuntimeUnknownResolver.builder() - .setResolver(context.variableResolver()) - .setAttributeResolver(context.createAttributeResolver()) - .build(), - lateBoundFunctionResolver, - listener); - } else { - if (lateBoundFunctionResolver.isPresent()) { - return impl.eval(context.variableResolver(), lateBoundFunctionResolver.get(), listener); - } - return impl.eval(context.variableResolver(), listener); + Interpretable impl = getInterpretable(); + if (getOptions().enableUnknownTracking()) { + Preconditions.checkState( + impl instanceof UnknownTrackingInterpretable, + "Environment misconfigured. Requested unknown tracking without a compatible" + + " implementation."); + + UnknownTrackingInterpretable interpreter = (UnknownTrackingInterpretable) impl; + return interpreter.evalTrackingUnknowns( + RuntimeUnknownResolver.builder() + .setResolver(context.variableResolver()) + .setAttributeResolver(context.createAttributeResolver()) + .build(), + lateBoundFunctionResolver, + listener); + } else { + if (lateBoundFunctionResolver.isPresent()) { + return impl.eval(context.variableResolver(), lateBoundFunctionResolver.get(), listener); } - } catch (InterpreterException e) { - throw unwrapOrCreateEvaluationException(e); + return impl.eval(context.variableResolver(), listener); } } @@ -229,16 +224,6 @@ private Object evalInternal( static Program from(Interpretable interpretable, CelOptions options) { return new AutoValue_CelRuntime_Program(interpretable, options); } - - @CheckReturnValue - private static CelEvaluationException unwrapOrCreateEvaluationException( - InterpreterException e) { - if (e.getCause() instanceof CelEvaluationException) { - return (CelEvaluationException) e.getCause(); - } - - return new CelEvaluationException(e.getMessage(), e.getCause(), e.getErrorCode()); - } } /** diff --git a/runtime/src/main/java/dev/cel/runtime/CelRuntimeLegacyImpl.java b/runtime/src/main/java/dev/cel/runtime/CelRuntimeLegacyImpl.java index dbfaf98c..7ff19fd1 100644 --- a/runtime/src/main/java/dev/cel/runtime/CelRuntimeLegacyImpl.java +++ b/runtime/src/main/java/dev/cel/runtime/CelRuntimeLegacyImpl.java @@ -257,18 +257,7 @@ public CelRuntimeLegacyImpl build() { .forEach( (String overloadId, CelFunctionBinding func) -> dispatcher.add( - overloadId, - func.getArgTypes(), - (args) -> { - try { - return func.getDefinition().apply(args); - } catch (CelEvaluationException e) { - throw new InterpreterException.Builder(e.getMessage()) - .setCause(e) - .setErrorCode(e.getErrorCode()) - .build(); - } - })); + overloadId, func.getArgTypes(), (args) -> func.getDefinition().apply(args))); RuntimeTypeProvider runtimeTypeProvider; diff --git a/runtime/src/main/java/dev/cel/runtime/CelStandardFunctions.java b/runtime/src/main/java/dev/cel/runtime/CelStandardFunctions.java index 2a99858a..3d458bf7 100644 --- a/runtime/src/main/java/dev/cel/runtime/CelStandardFunctions.java +++ b/runtime/src/main/java/dev/cel/runtime/CelStandardFunctions.java @@ -30,8 +30,10 @@ import com.google.protobuf.util.Timestamps; import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; +import dev.cel.common.CelRuntimeException; import dev.cel.common.internal.ComparisonFunctions; import dev.cel.common.internal.DynamicProto; +import dev.cel.common.internal.SafeStringFormatter; import dev.cel.runtime.CelRuntime.CelFunctionBinding; import dev.cel.runtime.CelStandardFunctions.StandardFunction.Overload.Arithmetic; import dev.cel.runtime.CelStandardFunctions.StandardFunction.Overload.BooleanOperator; @@ -316,10 +318,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.int64Add(x, y, bindingHelper.celOptions); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } })), ADD_UINT64( @@ -333,10 +332,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.uint64Add(x, y); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } }); } else { @@ -348,10 +344,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.uint64Add(x, y, bindingHelper.celOptions); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } }); } @@ -396,10 +389,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.int64Subtract(x, y, bindingHelper.celOptions); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } })), SUBTRACT_TIMESTAMP_TIMESTAMP( @@ -427,10 +417,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.uint64Subtract(x, y); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } }); } else { @@ -442,10 +429,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.uint64Subtract(x, y, bindingHelper.celOptions); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } }); } @@ -471,10 +455,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.int64Multiply(x, y, bindingHelper.celOptions); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } })), MULTIPLY_DOUBLE( @@ -492,10 +473,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.uint64Multiply(x, y); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } }); } else { @@ -507,10 +485,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.uint64Multiply(x, y, bindingHelper.celOptions); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } }); } @@ -529,10 +504,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.int64Divide(x, y, bindingHelper.celOptions); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } })), DIVIDE_UINT64( @@ -562,10 +534,7 @@ public enum Arithmetic implements StandardOverload { try { return x % y; } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } })), MODULO_UINT64( @@ -593,10 +562,7 @@ public enum Arithmetic implements StandardOverload { try { return RuntimeHelpers.int64Negate(x, bindingHelper.celOptions); } catch (ArithmeticException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(getArithmeticErrorCode(e)) - .build(); + throw new CelRuntimeException(e, getArithmeticErrorCode(e)); } })), NEGATE_DOUBLE( @@ -718,10 +684,11 @@ public enum Conversions implements StandardOverload { case "0": return false; default: - throw CelEvaluationExceptionBuilder.newBuilder( - "Type conversion error from 'string' to 'bool': [%s]", str) - .setErrorCode(CelErrorCode.BAD_FORMAT) - .build(); + throw new CelRuntimeException( + new IllegalArgumentException( + SafeStringFormatter.format( + "Type conversion error from 'string' to 'bool': [%s]", str)), + CelErrorCode.BAD_FORMAT); } })), // Int conversions @@ -738,10 +705,10 @@ public enum Conversions implements StandardOverload { return RuntimeHelpers.doubleToLongChecked(arg) .orElseThrow( () -> - CelEvaluationExceptionBuilder.newBuilder( - "double is out of range for int") - .setErrorCode(CelErrorCode.NUMERIC_OVERFLOW) - .build()); + new CelRuntimeException( + new IllegalArgumentException( + "double is out of range for int"), + CelErrorCode.NUMERIC_OVERFLOW)); } return arg.longValue(); })), @@ -754,10 +721,7 @@ public enum Conversions implements StandardOverload { try { return Long.parseLong(arg); } catch (NumberFormatException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(CelErrorCode.BAD_FORMAT) - .build(); + throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); } })), TIMESTAMP_TO_INT64( @@ -772,9 +736,9 @@ public enum Conversions implements StandardOverload { UnsignedLong.class, (UnsignedLong arg) -> { if (arg.compareTo(UnsignedLong.valueOf(Long.MAX_VALUE)) > 0) { - throw CelEvaluationExceptionBuilder.newBuilder("unsigned out of int range") - .setErrorCode(CelErrorCode.NUMERIC_OVERFLOW) - .build(); + throw new CelRuntimeException( + new IllegalArgumentException("unsigned out of int range"), + CelErrorCode.NUMERIC_OVERFLOW); } return arg.longValue(); }); @@ -784,9 +748,9 @@ public enum Conversions implements StandardOverload { Long.class, (Long arg) -> { if (bindingHelper.celOptions.errorOnIntWrap() && arg < 0) { - throw CelEvaluationExceptionBuilder.newBuilder("unsigned out of int range") - .setErrorCode(CelErrorCode.NUMERIC_OVERFLOW) - .build(); + throw new CelRuntimeException( + new IllegalArgumentException("unsigned out of int range"), + CelErrorCode.NUMERIC_OVERFLOW); } return arg; }); @@ -810,9 +774,9 @@ public enum Conversions implements StandardOverload { Long.class, (Long arg) -> { if (bindingHelper.celOptions.errorOnIntWrap() && arg < 0) { - throw CelEvaluationExceptionBuilder.newBuilder("int out of uint range") - .setErrorCode(CelErrorCode.NUMERIC_OVERFLOW) - .build(); + throw new CelRuntimeException( + new IllegalArgumentException("int out of uint range"), + CelErrorCode.NUMERIC_OVERFLOW); } return UnsignedLong.valueOf(arg); }); @@ -822,9 +786,9 @@ public enum Conversions implements StandardOverload { Long.class, (Long arg) -> { if (bindingHelper.celOptions.errorOnIntWrap() && arg < 0) { - throw CelEvaluationExceptionBuilder.newBuilder("int out of uint range") - .setErrorCode(CelErrorCode.NUMERIC_OVERFLOW) - .build(); + throw new CelRuntimeException( + new IllegalArgumentException("int out of uint range"), + CelErrorCode.NUMERIC_OVERFLOW); } return arg; }); @@ -841,10 +805,9 @@ public enum Conversions implements StandardOverload { return RuntimeHelpers.doubleToUnsignedChecked(arg) .orElseThrow( () -> - CelEvaluationExceptionBuilder.newBuilder( - "double out of uint range") - .setErrorCode(CelErrorCode.NUMERIC_OVERFLOW) - .build()); + new CelRuntimeException( + new IllegalArgumentException("double out of uint range"), + CelErrorCode.NUMERIC_OVERFLOW)); } return UnsignedLong.valueOf(BigDecimal.valueOf(arg).toBigInteger()); }); @@ -858,10 +821,9 @@ public enum Conversions implements StandardOverload { .map(UnsignedLong::longValue) .orElseThrow( () -> - CelEvaluationExceptionBuilder.newBuilder( - "double out of uint range") - .setErrorCode(CelErrorCode.NUMERIC_OVERFLOW) - .build()); + new CelRuntimeException( + new IllegalArgumentException("double out of uint range"), + CelErrorCode.NUMERIC_OVERFLOW)); } return arg.longValue(); }); @@ -877,10 +839,7 @@ public enum Conversions implements StandardOverload { try { return UnsignedLong.valueOf(arg); } catch (NumberFormatException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(CelErrorCode.BAD_FORMAT) - .build(); + throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); } }); } else { @@ -891,10 +850,7 @@ public enum Conversions implements StandardOverload { try { return UnsignedLongs.parseUnsignedLong(arg); } catch (NumberFormatException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(CelErrorCode.BAD_FORMAT) - .build(); + throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); } }); } @@ -915,10 +871,7 @@ public enum Conversions implements StandardOverload { try { return Double.parseDouble(arg); } catch (NumberFormatException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(CelErrorCode.BAD_FORMAT) - .build(); + throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); } })), UINT64_TO_DOUBLE( @@ -985,10 +938,7 @@ public enum Conversions implements StandardOverload { try { return RuntimeHelpers.createDurationFromString(d); } catch (IllegalArgumentException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(CelErrorCode.BAD_FORMAT) - .build(); + throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); } })), @@ -1001,10 +951,7 @@ public enum Conversions implements StandardOverload { try { return Timestamps.parse(ts); } catch (ParseException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(CelErrorCode.BAD_FORMAT) - .build(); + throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); } })), TIMESTAMP_TO_TIMESTAMP( @@ -1045,10 +992,7 @@ public enum StringMatchers implements StandardOverload { try { return RuntimeHelpers.matches(string, regexp, bindingHelper.celOptions); } catch (RuntimeException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(CelErrorCode.INVALID_ARGUMENT) - .build(); + throw new CelRuntimeException(e, CelErrorCode.INVALID_ARGUMENT); } })), // Duplicate receiver-style matches overload. @@ -1062,10 +1006,7 @@ public enum StringMatchers implements StandardOverload { try { return RuntimeHelpers.matches(string, regexp, bindingHelper.celOptions); } catch (RuntimeException e) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) - .setCause(e) - .setErrorCode(CelErrorCode.INVALID_ARGUMENT) - .build(); + throw new CelRuntimeException(e, CelErrorCode.INVALID_ARGUMENT); } })), CONTAINS_STRING( @@ -2070,8 +2011,7 @@ private static CelErrorCode getArithmeticErrorCode(ArithmeticException e) { * * @return If an Invalid timezone is supplied. */ - private static LocalDateTime newLocalDateTime(Timestamp ts, String tz) - throws CelEvaluationException { + private static LocalDateTime newLocalDateTime(Timestamp ts, String tz) { return Instant.ofEpochSecond(ts.getSeconds(), ts.getNanos()) .atZone(timeZone(tz)) .toLocalDateTime(); @@ -2082,9 +2022,8 @@ private static LocalDateTime newLocalDateTime(Timestamp ts, String tz) * * @param tz the ID of the datetime zone * @return the ZoneId object - * @throws CelEvaluationException if there is an invalid timezone */ - private static ZoneId timeZone(String tz) throws CelEvaluationException { + private static ZoneId timeZone(String tz) { try { return ZoneId.of(tz); } catch (DateTimeException e) { @@ -2093,7 +2032,7 @@ private static ZoneId timeZone(String tz) throws CelEvaluationException { try { int ind = tz.indexOf(":"); if (ind == -1) { - throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()).build(); + throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); } int hourOffset = Integer.parseInt(tz.substring(0, ind)); @@ -2108,7 +2047,7 @@ private static ZoneId timeZone(String tz) throws CelEvaluationException { return ZoneId.of(formattedOffset); } catch (DateTimeException e2) { - throw CelEvaluationExceptionBuilder.newBuilder(e2.getMessage()).build(); + throw new CelRuntimeException(e2, CelErrorCode.BAD_FORMAT); } } } diff --git a/runtime/src/main/java/dev/cel/runtime/DefaultDispatcher.java b/runtime/src/main/java/dev/cel/runtime/DefaultDispatcher.java index fc047684..a30e9d26 100644 --- a/runtime/src/main/java/dev/cel/runtime/DefaultDispatcher.java +++ b/runtime/src/main/java/dev/cel/runtime/DefaultDispatcher.java @@ -22,7 +22,6 @@ import javax.annotation.concurrent.ThreadSafe; import com.google.errorprone.annotations.concurrent.GuardedBy; import dev.cel.common.CelErrorCode; -import dev.cel.common.CelException; import dev.cel.common.annotations.Internal; import java.util.ArrayList; import java.util.HashMap; @@ -83,7 +82,7 @@ public synchronized void add( @Override public synchronized Optional findOverload( - String functionName, List overloadIds, Object[] args) throws CelException { + String functionName, List overloadIds, Object[] args) throws CelEvaluationException { return DefaultDispatcher.findOverload(functionName, overloadIds, overloads, args); } @@ -93,7 +92,7 @@ public static Optional findOverload( List overloadIds, Map overloads, Object[] args) - throws CelException { + throws CelEvaluationException { int matchingOverloadCount = 0; ResolvedOverload match = null; List candidates = null; @@ -114,7 +113,7 @@ public static Optional findOverload( } if (matchingOverloadCount > 1) { - throw new InterpreterException.Builder( + throw CelEvaluationExceptionBuilder.newBuilder( "Ambiguous overloads for function '%s'. Matching candidates: %s", functionName, Joiner.on(", ").join(candidates)) .setErrorCode(CelErrorCode.AMBIGUOUS_OVERLOAD) @@ -138,7 +137,8 @@ private ImmutableCopy(Map overloads) { @Override public Optional findOverload( - String functionName, List overloadIds, Object[] args) throws CelException { + String functionName, List overloadIds, Object[] args) + throws CelEvaluationException { return DefaultDispatcher.findOverload(functionName, overloadIds, overloads, args); } diff --git a/runtime/src/main/java/dev/cel/runtime/DefaultInterpreter.java b/runtime/src/main/java/dev/cel/runtime/DefaultInterpreter.java index 0db9587b..f10d62ad 100644 --- a/runtime/src/main/java/dev/cel/runtime/DefaultInterpreter.java +++ b/runtime/src/main/java/dev/cel/runtime/DefaultInterpreter.java @@ -24,8 +24,8 @@ import javax.annotation.concurrent.ThreadSafe; import dev.cel.common.CelAbstractSyntaxTree; import dev.cel.common.CelErrorCode; -import dev.cel.common.CelException; import dev.cel.common.CelOptions; +import dev.cel.common.CelRuntimeException; import dev.cel.common.annotations.Internal; import dev.cel.common.ast.CelConstant; import dev.cel.common.ast.CelExpr; @@ -131,14 +131,14 @@ private static final class DefaultInterpretable } @Override - public Object eval(GlobalResolver resolver) throws InterpreterException { + public Object eval(GlobalResolver resolver) throws CelEvaluationException { // Result is already unwrapped from IntermediateResult. return eval(resolver, CelEvaluationListener.noOpListener()); } @Override public Object eval(GlobalResolver resolver, CelEvaluationListener listener) - throws InterpreterException { + throws CelEvaluationException { return evalTrackingUnknowns( RuntimeUnknownResolver.fromResolver(resolver), Optional.empty(), listener); } @@ -148,7 +148,7 @@ public Object eval( GlobalResolver resolver, FunctionResolver lateBoundFunctionResolver, CelEvaluationListener listener) - throws InterpreterException { + throws CelEvaluationException { return evalTrackingUnknowns( RuntimeUnknownResolver.fromResolver(resolver), Optional.of(lateBoundFunctionResolver), @@ -160,7 +160,7 @@ public Object evalTrackingUnknowns( RuntimeUnknownResolver resolver, Optional functionResolver, CelEvaluationListener listener) - throws InterpreterException { + throws CelEvaluationException { int comprehensionMaxIterations = celOptions.enableComprehension() ? celOptions.comprehensionMaxIterations() : 0; ExecutionFrame frame = @@ -170,7 +170,7 @@ public Object evalTrackingUnknowns( } private IntermediateResult evalInternal(ExecutionFrame frame, CelExpr expr) - throws InterpreterException { + throws CelEvaluationException { try { ExprKind.Kind exprKind = expr.exprKind().getKind(); IntermediateResult result; @@ -205,9 +205,14 @@ private IntermediateResult evalInternal(ExecutionFrame frame, CelExpr expr) } frame.getEvaluationListener().callback(expr, result.value()); return result; + } catch (CelRuntimeException e) { + throw CelEvaluationExceptionBuilder.newBuilder(e) + .setMetadata(metadata, expr.id()) + .build(); } catch (RuntimeException e) { - throw new InterpreterException.Builder(e, e.getMessage()) - .setLocation(metadata, expr.id()) + throw CelEvaluationExceptionBuilder.newBuilder(e.getMessage()) + .setCause(e) + // .setMetadata(metadata, expr.id()) TODO: Uncomment in the upcoming cl .build(); } } @@ -247,7 +252,7 @@ private Object evalConstant( } private IntermediateResult evalIdent(ExecutionFrame frame, CelExpr expr) - throws InterpreterException { + throws CelEvaluationException { CelReference reference = ast.getReferenceOrThrow(expr.id()); if (reference.value().isPresent()) { return IntermediateResult.create(evalConstant(frame, expr, reference.value().get())); @@ -256,7 +261,7 @@ private IntermediateResult evalIdent(ExecutionFrame frame, CelExpr expr) } private IntermediateResult resolveIdent(ExecutionFrame frame, CelExpr expr, String name) - throws InterpreterException { + throws CelEvaluationException { // Check whether the type exists in the type check map as a 'type'. Optional checkedType = ast.getType(expr.id()); if (checkedType.isPresent() && checkedType.get().kind() == CelKind.TYPE) { @@ -283,7 +288,7 @@ private IntermediateResult resolveIdent(ExecutionFrame frame, CelExpr expr, Stri } private IntermediateResult evalSelect(ExecutionFrame frame, CelExpr expr, CelSelect selectExpr) - throws InterpreterException { + throws CelEvaluationException { Optional referenceOptional = ast.getReference(expr.id()); if (referenceOptional.isPresent()) { CelReference reference = referenceOptional.get(); @@ -301,7 +306,7 @@ private IntermediateResult evalSelect(ExecutionFrame frame, CelExpr expr, CelSel private IntermediateResult evalFieldSelect( ExecutionFrame frame, CelExpr expr, CelExpr operandExpr, String field, boolean isTestOnly) - throws InterpreterException { + throws CelEvaluationException { // This indicates this is a field selection on the operand. IntermediateResult operandResult = evalInternal(frame, operandExpr); Object operand = operandResult.value(); @@ -330,7 +335,7 @@ private IntermediateResult evalFieldSelect( } private IntermediateResult evalCall(ExecutionFrame frame, CelExpr expr, CelCall callExpr) - throws InterpreterException { + throws CelEvaluationException { CelReference reference = ast.getReferenceOrThrow(expr.id()); Preconditions.checkState(!reference.overloadIds().isEmpty()); @@ -412,14 +417,16 @@ private IntermediateResult evalCall(ExecutionFrame frame, CelExpr expr, CelCall dispatchResult = typeProvider.adapt(dispatchResult); } return IntermediateResult.create(attr, dispatchResult); - } catch (CelException ce) { - throw InterpreterException.wrapOrThrow(metadata, expr.id(), ce); + } catch (CelRuntimeException ce) { + throw CelEvaluationExceptionBuilder.newBuilder(ce) + // .setMetadata(metadata, expr.id()) // TODO: Uncomment in the upcoming cl + .build(); } catch (RuntimeException e) { - throw new InterpreterException.Builder( - e, + throw CelEvaluationExceptionBuilder.newBuilder( "Function '%s' failed with arg(s) '%s'", - overload.getOverloadId(), - Joiner.on(", ").join(argArray)) + overload.getOverloadId(), Joiner.on(", ").join(argArray)) + // .setMetadata(metadata, expr.id()) // TODO: Uncomment in the upcoming cl + .setCause(e) .build(); } } @@ -430,7 +437,7 @@ private ResolvedOverload findOverloadOrThrow( String functionName, List overloadIds, Object[] args) - throws InterpreterException { + throws CelEvaluationException { try { Optional funcImpl = dispatcher.findOverload(functionName, overloadIds, args); @@ -441,14 +448,16 @@ private ResolvedOverload findOverloadOrThrow( .findOverload(functionName, overloadIds, args) .orElseThrow( () -> - new InterpreterException.Builder( + CelEvaluationExceptionBuilder.newBuilder( "No matching overload for function '%s'. Overload candidates: %s", functionName, Joiner.on(",").join(overloadIds)) .setErrorCode(CelErrorCode.OVERLOAD_NOT_FOUND) - .setLocation(metadata, expr.id()) + .setMetadata(metadata, expr.id()) .build()); - } catch (CelException e) { - throw InterpreterException.wrapOrThrow(metadata, expr.id(), e); + } catch (CelRuntimeException e) { + throw CelEvaluationExceptionBuilder.newBuilder(e) + // .setMetadata(metadata, expr.id()) // TODO: Uncomment in the upcoming cl + .build(); } } @@ -481,7 +490,7 @@ private Optional maybeContainerIndexAttribute( } private IntermediateResult evalConditional(ExecutionFrame frame, CelCall callExpr) - throws InterpreterException { + throws CelEvaluationException { IntermediateResult condition = evalBooleanStrict(frame, callExpr.args().get(0)); if (celOptions.enableShortCircuiting()) { if (isUnknownValue(condition.value())) { @@ -504,7 +513,7 @@ private IntermediateResult evalConditional(ExecutionFrame frame, CelCall callExp } private IntermediateResult mergeBooleanUnknowns(IntermediateResult lhs, IntermediateResult rhs) - throws InterpreterException { + throws CelEvaluationException { // TODO: migrate clients to a common type that reports both expr-id unknowns // and attribute sets. if (lhs.value() instanceof CelUnknownSet && rhs.value() instanceof CelUnknownSet) { @@ -540,7 +549,7 @@ private boolean canShortCircuit(IntermediateResult result, ShortCircuitableOpera } private IntermediateResult evalLogicalOr(ExecutionFrame frame, CelCall callExpr) - throws InterpreterException { + throws CelEvaluationException { IntermediateResult left; IntermediateResult right; if (celOptions.enableShortCircuiting()) { @@ -573,7 +582,7 @@ private IntermediateResult evalLogicalOr(ExecutionFrame frame, CelCall callExpr) } private IntermediateResult evalLogicalAnd(ExecutionFrame frame, CelCall callExpr) - throws InterpreterException { + throws CelEvaluationException { IntermediateResult left; IntermediateResult right; if (celOptions.enableShortCircuiting()) { @@ -620,7 +629,7 @@ private IntermediateResult evalNotStrictlyFalse(ExecutionFrame frame, CelCall ca } private IntermediateResult evalType(ExecutionFrame frame, CelCall callExpr) - throws InterpreterException { + throws CelEvaluationException { CelExpr typeExprArg = callExpr.args().get(0); IntermediateResult argResult = evalInternal(frame, typeExprArg); // Type is a strict function. Early return if the argument is an error or an unknown. @@ -632,12 +641,12 @@ private IntermediateResult evalType(ExecutionFrame frame, CelCall callExpr) ast.getType(typeExprArg.id()) .orElseThrow( () -> - new InterpreterException.Builder( + CelEvaluationExceptionBuilder.newBuilder( "expected a runtime type for '%s' from checked expression, but found" + " none.", argResult.getClass().getSimpleName()) .setErrorCode(CelErrorCode.TYPE_NOT_FOUND) - .setLocation(metadata, typeExprArg.id()) + .setMetadata(metadata, typeExprArg.id()) .build()); CelType checkedTypeValue = CelTypeResolver.adaptType(checkedType); @@ -646,14 +655,14 @@ private IntermediateResult evalType(ExecutionFrame frame, CelCall callExpr) } private IntermediateResult evalOptionalOr(ExecutionFrame frame, CelCall callExpr) - throws InterpreterException { + throws CelEvaluationException { CelExpr lhsExpr = callExpr.target().get(); IntermediateResult lhsResult = evalInternal(frame, lhsExpr); if (!(lhsResult.value() instanceof Optional)) { - throw new InterpreterException.Builder( + throw CelEvaluationExceptionBuilder.newBuilder( "expected optional value, found: %s", lhsResult.value()) .setErrorCode(CelErrorCode.INVALID_ARGUMENT) - .setLocation(metadata, lhsExpr.id()) + .setMetadata(metadata, lhsExpr.id()) .build(); } @@ -668,14 +677,14 @@ private IntermediateResult evalOptionalOr(ExecutionFrame frame, CelCall callExpr } private IntermediateResult evalOptionalOrValue(ExecutionFrame frame, CelCall callExpr) - throws InterpreterException { + throws CelEvaluationException { CelExpr lhsExpr = callExpr.target().get(); IntermediateResult lhsResult = evalInternal(frame, lhsExpr); if (!(lhsResult.value() instanceof Optional)) { - throw new InterpreterException.Builder( + throw CelEvaluationExceptionBuilder.newBuilder( "expected optional value, found: %s", lhsResult.value()) .setErrorCode(CelErrorCode.INVALID_ARGUMENT) - .setLocation(metadata, lhsExpr.id()) + .setMetadata(metadata, lhsExpr.id()) .build(); } @@ -690,7 +699,7 @@ private IntermediateResult evalOptionalOrValue(ExecutionFrame frame, CelCall cal } private Optional maybeEvalOptionalSelectField( - ExecutionFrame frame, CelExpr expr, CelCall callExpr) throws InterpreterException { + ExecutionFrame frame, CelExpr expr, CelCall callExpr) throws CelEvaluationException { CelExpr operand = callExpr.args().get(0); IntermediateResult lhsResult = evalInternal(frame, operand); if ((lhsResult.value() instanceof Map)) { @@ -713,13 +722,14 @@ private Optional maybeEvalOptionalSelectField( } private IntermediateResult evalBoolean(ExecutionFrame frame, CelExpr expr, boolean strict) - throws InterpreterException { + throws CelEvaluationException { IntermediateResult value = strict ? evalInternal(frame, expr) : evalNonstrictly(frame, expr); if (!(value.value() instanceof Boolean) && !isUnknownOrError(value.value())) { - throw new InterpreterException.Builder("expected boolean value, found: %s", value.value()) + throw CelEvaluationExceptionBuilder.newBuilder( + "expected boolean value, found: %s", value.value()) .setErrorCode(CelErrorCode.INVALID_ARGUMENT) - .setLocation(metadata, expr.id()) + .setMetadata(metadata, expr.id()) .build(); } @@ -727,20 +737,20 @@ private IntermediateResult evalBoolean(ExecutionFrame frame, CelExpr expr, boole } private IntermediateResult evalBooleanStrict(ExecutionFrame frame, CelExpr expr) - throws InterpreterException { + throws CelEvaluationException { return evalBoolean(frame, expr, /* strict= */ true); } // Evaluate a non-strict boolean sub expression. - // Behaves the same as non-strict eval, but throws an InterpreterException if the result + // Behaves the same as non-strict eval, but throws a CelEvaluationException if the result // doesn't support CELs short-circuiting behavior (not an error, unknown or boolean). private IntermediateResult evalBooleanNonstrict(ExecutionFrame frame, CelExpr expr) - throws InterpreterException { + throws CelEvaluationException { return evalBoolean(frame, expr, /* strict= */ false); } private IntermediateResult evalList(ExecutionFrame frame, CelExpr unusedExpr, CelList listExpr) - throws InterpreterException { + throws CelEvaluationException { CallArgumentChecker argChecker = CallArgumentChecker.create(frame.getResolver()); List result = new ArrayList<>(listExpr.elements().size()); @@ -772,7 +782,7 @@ private IntermediateResult evalList(ExecutionFrame frame, CelExpr unusedExpr, Ce } private IntermediateResult evalMap(ExecutionFrame frame, CelMap mapExpr) - throws InterpreterException { + throws CelEvaluationException { CallArgumentChecker argChecker = CallArgumentChecker.create(frame.getResolver()); @@ -786,9 +796,10 @@ private IntermediateResult evalMap(ExecutionFrame frame, CelMap mapExpr) argChecker.checkArg(valueResult); if (celOptions.errorOnDuplicateMapKeys() && result.containsKey(keyResult.value())) { - throw new InterpreterException.Builder("duplicate map key [%s]", keyResult.value()) + throw CelEvaluationExceptionBuilder.newBuilder( + "duplicate map key [%s]", keyResult.value()) .setErrorCode(CelErrorCode.DUPLICATE_ATTRIBUTE) - .setLocation(metadata, entry.id()) + .setMetadata(metadata, entry.id()) .build(); } @@ -811,7 +822,7 @@ private IntermediateResult evalMap(ExecutionFrame frame, CelMap mapExpr) } private IntermediateResult evalStruct(ExecutionFrame frame, CelExpr expr, CelStruct structExpr) - throws InterpreterException { + throws CelEvaluationException { CelReference reference = ast.getReference(expr.id()) .orElseThrow( @@ -866,7 +877,7 @@ private IntermediateResult evalNonstrictly(ExecutionFrame frame, CelExpr expr) { @SuppressWarnings("unchecked") private IntermediateResult evalComprehension( ExecutionFrame frame, CelExpr unusedExpr, CelComprehension compre) - throws InterpreterException { + throws CelEvaluationException { String accuVar = compre.accuVar(); String iterVar = compre.iterVar(); IntermediateResult iterRangeRaw = evalInternal(frame, compre.iterRange()); @@ -879,11 +890,11 @@ private IntermediateResult evalComprehension( } else if (iterRangeRaw.value() instanceof Map) { iterRange = ((Map) iterRangeRaw.value()).keySet(); } else { - throw new InterpreterException.Builder( + throw CelEvaluationExceptionBuilder.newBuilder( "expected a list or a map for iteration range but got '%s'", iterRangeRaw.value().getClass().getSimpleName()) .setErrorCode(CelErrorCode.INVALID_ARGUMENT) - .setLocation(metadata, compre.iterRange().id()) + .setMetadata(metadata, compre.iterRange().id()) .build(); } IntermediateResult accuValue; @@ -924,7 +935,7 @@ private IntermediateResult evalComprehension( } private IntermediateResult evalCelBlock( - ExecutionFrame frame, CelExpr unusedExpr, CelCall blockCall) throws InterpreterException { + ExecutionFrame frame, CelExpr unusedExpr, CelCall blockCall) throws CelEvaluationException { CelList exprList = blockCall.args().get(0).list(); Map blockList = new HashMap<>(); for (int index = 0; index < exprList.elements().size(); index++) { @@ -997,19 +1008,19 @@ private RuntimeUnknownResolver getResolver() { } private Optional findOverload( - String function, List overloadIds, Object[] args) throws CelException { + String function, List overloadIds, Object[] args) throws CelEvaluationException { if (lateBoundFunctionResolver.isPresent()) { return lateBoundFunctionResolver.get().findOverload(function, overloadIds, args); } return Optional.empty(); } - private void incrementIterations() throws InterpreterException { + private void incrementIterations() throws CelEvaluationException { if (maxIterations < 0) { return; } if (++iterations > maxIterations) { - throw new InterpreterException.Builder( + throw CelEvaluationExceptionBuilder.newBuilder( String.format("Iteration budget exceeded: %d", maxIterations)) .setErrorCode(CelErrorCode.ITERATION_BUDGET_EXCEEDED) .build(); diff --git a/runtime/src/main/java/dev/cel/runtime/FunctionOverload.java b/runtime/src/main/java/dev/cel/runtime/FunctionOverload.java index 132a128d..4271801c 100644 --- a/runtime/src/main/java/dev/cel/runtime/FunctionOverload.java +++ b/runtime/src/main/java/dev/cel/runtime/FunctionOverload.java @@ -15,7 +15,6 @@ package dev.cel.runtime; import com.google.errorprone.annotations.Immutable; -import dev.cel.common.CelException; /** Interface describing the general signature of all CEL custom function implementations. */ @FunctionalInterface @@ -23,7 +22,7 @@ public interface FunctionOverload { /** Evaluate a set of arguments throwing a {@code CelException} on error. */ - Object apply(Object[] args) throws CelException; + Object apply(Object[] args) throws CelEvaluationException; /** * Helper interface for describing unary functions where the type-parameter is used to improve @@ -32,7 +31,7 @@ public interface FunctionOverload { @Immutable @FunctionalInterface interface Unary { - Object apply(T arg) throws CelException; + Object apply(T arg) throws CelEvaluationException; } /** @@ -42,6 +41,6 @@ interface Unary { @Immutable @FunctionalInterface interface Binary { - Object apply(T1 arg1, T2 arg2) throws CelException; + Object apply(T1 arg1, T2 arg2) throws CelEvaluationException; } } diff --git a/runtime/src/main/java/dev/cel/runtime/FunctionResolver.java b/runtime/src/main/java/dev/cel/runtime/FunctionResolver.java index 4d7614df..c4f626ff 100644 --- a/runtime/src/main/java/dev/cel/runtime/FunctionResolver.java +++ b/runtime/src/main/java/dev/cel/runtime/FunctionResolver.java @@ -15,7 +15,6 @@ package dev.cel.runtime; import javax.annotation.concurrent.ThreadSafe; -import dev.cel.common.CelException; import dev.cel.common.annotations.Internal; import java.util.List; import java.util.Optional; @@ -38,8 +37,8 @@ public interface FunctionResolver { * from this list with matching arguments. * @param args The arguments to pass to the function. * @return an optional value of the resolved overload. - * @throws CelException if the overload resolution is ambiguous, + * @throws CelEvaluationException if the overload resolution is ambiguous, */ Optional findOverload( - String functionName, List overloadIds, Object[] args) throws CelException; + String functionName, List overloadIds, Object[] args) throws CelEvaluationException; } diff --git a/runtime/src/main/java/dev/cel/runtime/Interpretable.java b/runtime/src/main/java/dev/cel/runtime/Interpretable.java index c967af92..82701eaa 100644 --- a/runtime/src/main/java/dev/cel/runtime/Interpretable.java +++ b/runtime/src/main/java/dev/cel/runtime/Interpretable.java @@ -27,14 +27,15 @@ public interface Interpretable { /** Runs interpretation with the given activation which supplies name/value bindings. */ - Object eval(GlobalResolver resolver) throws InterpreterException; + Object eval(GlobalResolver resolver) throws CelEvaluationException; /** * Runs interpretation with the given activation which supplies name/value bindings. * *

This method allows for evaluation listeners to be provided per-evaluation. */ - Object eval(GlobalResolver resolver, CelEvaluationListener listener) throws InterpreterException; + Object eval(GlobalResolver resolver, CelEvaluationListener listener) + throws CelEvaluationException; /** * Runs interpretation with the given activation which supplies name/value bindings. @@ -48,5 +49,5 @@ Object eval( GlobalResolver resolver, FunctionResolver lateBoundFunctionResolver, CelEvaluationListener listener) - throws InterpreterException; + throws CelEvaluationException; } diff --git a/runtime/src/main/java/dev/cel/runtime/InterpreterException.java b/runtime/src/main/java/dev/cel/runtime/InterpreterException.java deleted file mode 100644 index 6a30469a..00000000 --- a/runtime/src/main/java/dev/cel/runtime/InterpreterException.java +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2022 Google LLC -// -// 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 -// -// https://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 dev.cel.runtime; - -import com.google.errorprone.annotations.CanIgnoreReturnValue; -import com.google.errorprone.annotations.CheckReturnValue; -import dev.cel.common.CelErrorCode; -import dev.cel.common.CelException; -import dev.cel.common.CelRuntimeException; -import dev.cel.common.annotations.Internal; -import dev.cel.common.internal.SafeStringFormatter; -import org.jspecify.annotations.Nullable; - -/** - * An exception produced during interpretation of expressions. - * - *

TODO: Remove in favor of creating exception types that corresponds to the error - * code. - * - *

CEL Library Internals. Do Not Use. - */ -@Internal -public class InterpreterException extends CelException { - - /** Builder for InterpreterException. */ - public static class Builder { - private final String message; - @Nullable private String location; - private int position; - private Throwable cause; - private CelErrorCode errorCode = CelErrorCode.INTERNAL_ERROR; - - @SuppressWarnings({"AnnotateFormatMethod"}) // Format strings are optional. - public Builder(String message, Object... args) { - this.message = SafeStringFormatter.format(message, args); - } - - @SuppressWarnings({"AnnotateFormatMethod"}) // Format strings are optional. - public Builder(RuntimeException e, String message, Object... args) { - if (e instanceof CelRuntimeException) { - CelRuntimeException celRuntimeException = (CelRuntimeException) e; - this.errorCode = celRuntimeException.getErrorCode(); - // CelRuntimeException is just a wrapper for the specific RuntimeException (typically - // IllegalArgumentException). The underlying cause and its message is what we are actually - // interested in. - this.cause = e.getCause(); - message = e.getCause().getMessage(); - } else { - this.cause = e; - } - - this.message = SafeStringFormatter.format(message, args); - } - - @CanIgnoreReturnValue - public Builder setLocation(@Nullable Metadata metadata, long exprId) { - if (metadata != null) { - this.location = metadata.getLocation(); - this.position = metadata.getPosition(exprId); - } - return this; - } - - @CanIgnoreReturnValue - public Builder setCause(Throwable cause) { - this.cause = cause; - return this; - } - - @CanIgnoreReturnValue - public Builder setErrorCode(CelErrorCode errorCode) { - this.errorCode = errorCode; - return this; - } - - @CheckReturnValue - public InterpreterException build() { - String exceptionMessage = message; - if (!exceptionMessage.startsWith("evaluation error")) { - // TODO: Temporary until interpreter exception is removed - exceptionMessage = - String.format( - "evaluation error%s: %s", - location != null ? " at " + location + ":" + position : "", message); - } - return new InterpreterException(exceptionMessage, cause, errorCode); - } - } - - public static InterpreterException wrapOrThrow(Metadata metadata, long exprId, Exception e) { - if (e instanceof InterpreterException) { - return (InterpreterException) e; - } - if (e instanceof CelException) { - return new InterpreterException.Builder(e.getMessage()) - .setCause(e.getCause()) - .setErrorCode(((CelException) e).getErrorCode()) - .build(); - } - return new InterpreterException.Builder(e.getMessage()).setCause(e).build(); - } - - public static InterpreterException wrapOrThrow(Exception e) { - return wrapOrThrow(null, 0, e); - } - - private InterpreterException(String message, Throwable cause, CelErrorCode errorCode) { - super(message, cause, errorCode); - } -} diff --git a/runtime/src/main/java/dev/cel/runtime/InterpreterUtil.java b/runtime/src/main/java/dev/cel/runtime/InterpreterUtil.java index cce47d62..cb9353dd 100644 --- a/runtime/src/main/java/dev/cel/runtime/InterpreterUtil.java +++ b/runtime/src/main/java/dev/cel/runtime/InterpreterUtil.java @@ -14,6 +14,7 @@ package dev.cel.runtime; +import com.google.errorprone.annotations.CheckReturnValue; import dev.cel.common.annotations.Internal; import java.util.LinkedHashSet; import java.util.Set; @@ -32,12 +33,13 @@ public final class InterpreterUtil { * {@link Throwable}. Applying {@code strict()} to such a value-or-throwable will re-throw the * proper exception. */ - public static Object strict(Object valueOrThrowable) throws InterpreterException { + @CheckReturnValue + public static Object strict(Object valueOrThrowable) throws CelEvaluationException { if (!(valueOrThrowable instanceof Throwable)) { return valueOrThrowable; } - if (valueOrThrowable instanceof InterpreterException) { - throw (InterpreterException) valueOrThrowable; + if (valueOrThrowable instanceof CelEvaluationException) { + throw (CelEvaluationException) valueOrThrowable; } if (valueOrThrowable instanceof RuntimeException) { throw (RuntimeException) valueOrThrowable; @@ -75,7 +77,7 @@ static CelUnknownSet combineUnknownExprValue(Object... objs) { * both of these operators. */ public static Object shortcircuitUnknownOrThrowable(Object left, Object right) - throws InterpreterException { + throws CelEvaluationException { // unknown unknown ==> unknown combined if (InterpreterUtil.isUnknown(left) && InterpreterUtil.isUnknown(right)) { return InterpreterUtil.combineUnknownExprValue(left, right); diff --git a/runtime/src/main/java/dev/cel/runtime/UnknownTrackingInterpretable.java b/runtime/src/main/java/dev/cel/runtime/UnknownTrackingInterpretable.java index a76c198c..4eaf08e6 100644 --- a/runtime/src/main/java/dev/cel/runtime/UnknownTrackingInterpretable.java +++ b/runtime/src/main/java/dev/cel/runtime/UnknownTrackingInterpretable.java @@ -37,5 +37,5 @@ Object evalTrackingUnknowns( RuntimeUnknownResolver resolver, Optional lateBoundFunctionResolver, CelEvaluationListener listener) - throws InterpreterException; + throws CelEvaluationException; } diff --git a/runtime/src/test/java/dev/cel/runtime/CelLateFunctionBindingsTest.java b/runtime/src/test/java/dev/cel/runtime/CelLateFunctionBindingsTest.java index c69a5320..e5a715af 100644 --- a/runtime/src/test/java/dev/cel/runtime/CelLateFunctionBindingsTest.java +++ b/runtime/src/test/java/dev/cel/runtime/CelLateFunctionBindingsTest.java @@ -19,7 +19,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.primitives.UnsignedLong; import dev.cel.common.CelErrorCode; -import dev.cel.common.CelException; import dev.cel.expr.conformance.proto3.TestAllTypes; import dev.cel.runtime.CelRuntime.CelFunctionBinding; import java.util.Optional; @@ -33,8 +32,7 @@ public final class CelLateFunctionBindingsTest { @Test - public void findOverload_singleMatchingFunction_isPresent() - throws CelException, InterpreterException { + public void findOverload_singleMatchingFunction_isPresent() throws Exception { CelLateFunctionBindings bindings = CelLateFunctionBindings.from( CelFunctionBinding.from("increment_int", Long.class, (arg) -> arg + 1), @@ -50,7 +48,7 @@ public void findOverload_singleMatchingFunction_isPresent() } @Test - public void findOverload_noMatchingFunctionSameArgCount_isEmpty() throws CelException { + public void findOverload_noMatchingFunctionSameArgCount_isEmpty() throws Exception { CelLateFunctionBindings bindings = CelLateFunctionBindings.from( CelFunctionBinding.from("increment_int", Long.class, (arg) -> arg + 1), @@ -63,7 +61,7 @@ public void findOverload_noMatchingFunctionSameArgCount_isEmpty() throws CelExce } @Test - public void findOverload_noMatchingFunctionDifferentArgCount_isEmpty() throws CelException { + public void findOverload_noMatchingFunctionDifferentArgCount_isEmpty() throws Exception { CelLateFunctionBindings bindings = CelLateFunctionBindings.from( CelFunctionBinding.from("increment_int", Long.class, (arg) -> arg + 1), @@ -78,7 +76,7 @@ public void findOverload_noMatchingFunctionDifferentArgCount_isEmpty() throws Ce } @Test - public void findOverload_badInput_throwsException() throws CelException { + public void findOverload_badInput_throwsException() throws Exception { CelLateFunctionBindings bindings = CelLateFunctionBindings.from( CelFunctionBinding.from( @@ -97,22 +95,22 @@ public void findOverload_badInput_throwsException() throws CelException { assertThat(overload).isPresent(); assertThat(overload.get().getOverloadId()).isEqualTo("increment_uint"); assertThat(overload.get().getParameterTypes()).containsExactly(UnsignedLong.class); - InterpreterException e = + CelEvaluationException e = Assert.assertThrows( - InterpreterException.class, + CelEvaluationException.class, () -> overload.get().getDefinition().apply(new Object[] {UnsignedLong.MAX_VALUE})); assertThat(e.getErrorCode()).isEqualTo(CelErrorCode.NUMERIC_OVERFLOW); } @Test - public void findOverload_multipleMatchingFunctions_throwsException() throws CelException { + public void findOverload_multipleMatchingFunctions_throwsException() throws Exception { CelLateFunctionBindings bindings = CelLateFunctionBindings.from( CelFunctionBinding.from("increment_int", Long.class, (arg) -> arg + 1), CelFunctionBinding.from("increment_uint", Long.class, (arg) -> arg + 2)); - InterpreterException e = + CelEvaluationException e = Assert.assertThrows( - InterpreterException.class, + CelEvaluationException.class, () -> bindings.findOverload( "increment", @@ -122,7 +120,7 @@ public void findOverload_multipleMatchingFunctions_throwsException() throws CelE } @Test - public void findOverload_nullPrimitiveArg_isEmpty() throws CelException { + public void findOverload_nullPrimitiveArg_isEmpty() throws Exception { CelLateFunctionBindings bindings = CelLateFunctionBindings.from( CelFunctionBinding.from("identity_int", Long.class, (arg) -> arg)); @@ -132,7 +130,7 @@ public void findOverload_nullPrimitiveArg_isEmpty() throws CelException { } @Test - public void findOverload_nullMessageArg_returnsOverload() throws CelException { + public void findOverload_nullMessageArg_returnsOverload() throws Exception { CelLateFunctionBindings bindings = CelLateFunctionBindings.from( CelFunctionBinding.from("identity_msg", TestAllTypes.class, (arg) -> arg)); diff --git a/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java b/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java index 0f34e9fe..556d6945 100644 --- a/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java +++ b/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java @@ -46,9 +46,9 @@ public void setup() { @Test public void findOverload_multipleMatches_throwsException() { - InterpreterException e = + CelEvaluationException e = Assert.assertThrows( - InterpreterException.class, + CelEvaluationException.class, () -> DefaultDispatcher.findOverload( "overloads",