From d71e979e1e4ee155738a68a700bed17e252a2c64 Mon Sep 17 00:00:00 2001 From: Sokwhan Huh Date: Tue, 2 Dec 2025 18:26:24 -0800 Subject: [PATCH] Introduce CEL exception classes that correspond to canonical error codes PiperOrigin-RevId: 839508913 --- common/BUILD.bazel | 7 -- common/exceptions/BUILD.bazel | 48 +++++++++ .../src/main/java/dev/cel/common/BUILD.bazel | 19 +--- .../java/dev/cel/common/CelException.java | 5 - .../dev/cel/common/exceptions/BUILD.bazel | 99 +++++++++++++++++++ .../CelAttributeNotFoundException.java | 56 +++++++++++ .../exceptions/CelBadFormatException.java | 31 ++++++ .../exceptions/CelDivideByZeroException.java | 20 ++-- .../CelIndexOutOfBoundsException.java | 27 +++++ .../CelInvalidArgumentException.java | 27 +++++ .../CelNumericOverflowException.java | 34 +++++++ .../{ => exceptions}/CelRuntimeException.java | 15 +-- .../java/dev/cel/common/internal/BUILD.bazel | 13 +-- .../cel/common/internal/DateTimeHelpers.java | 7 +- .../dev/cel/common/internal/ProtoAdapter.java | 7 +- .../cel/common/internal/ProtoLiteAdapter.java | 11 +-- .../main/java/dev/cel/extensions/BUILD.bazel | 1 + .../dev/cel/extensions/CelMathExtensions.java | 9 +- .../test/java/dev/cel/extensions/BUILD.bazel | 3 +- .../CelComprehensionsExtensionsTest.java | 8 +- .../src/main/java/dev/cel/runtime/BUILD.bazel | 32 +++--- .../CelEvaluationExceptionBuilder.java | 15 ++- .../runtime/CelValueRuntimeTypeProvider.java | 15 +-- .../dev/cel/runtime/DefaultInterpreter.java | 2 +- .../runtime/DescriptorMessageProvider.java | 22 +---- .../java/dev/cel/runtime/RuntimeEquality.java | 7 +- .../java/dev/cel/runtime/RuntimeHelpers.java | 41 ++++---- .../java/dev/cel/runtime/planner/BUILD.bazel | 2 +- .../cel/runtime/planner/PlannedProgram.java | 2 +- .../dev/cel/runtime/standard/AddOperator.java | 10 +- .../java/dev/cel/runtime/standard/BUILD.bazel | 98 ++++++------------ .../cel/runtime/standard/BoolFunction.java | 11 +-- .../cel/runtime/standard/DivideOperator.java | 6 +- .../cel/runtime/standard/DoubleFunction.java | 5 +- .../runtime/standard/DurationFunction.java | 7 +- .../dev/cel/runtime/standard/IntFunction.java | 18 ++-- .../cel/runtime/standard/MatchesFunction.java | 7 +- .../cel/runtime/standard/ModuloOperator.java | 6 +- .../runtime/standard/MultiplyOperator.java | 10 +- .../cel/runtime/standard/NegateOperator.java | 6 +- .../cel/runtime/standard/StringFunction.java | 15 +-- .../runtime/standard/SubtractOperator.java | 10 +- .../runtime/standard/TimestampFunction.java | 7 +- .../cel/runtime/standard/UintFunction.java | 26 ++--- .../src/test/java/dev/cel/runtime/BUILD.bazel | 5 +- .../CelEvaluationExceptionBuilderTest.java | 8 +- .../cel/runtime/CelRuntimeLegacyImplTest.java | 3 +- .../DescriptorMessageProviderTest.java | 8 +- .../ProtoMessageRuntimeEqualityTest.java | 2 +- .../ProtoMessageRuntimeHelpersTest.java | 21 ++-- .../java/dev/cel/runtime/planner/BUILD.bazel | 1 + .../runtime/planner/ProgramPlannerTest.java | 7 +- 52 files changed, 540 insertions(+), 342 deletions(-) create mode 100644 common/exceptions/BUILD.bazel create mode 100644 common/src/main/java/dev/cel/common/exceptions/BUILD.bazel create mode 100644 common/src/main/java/dev/cel/common/exceptions/CelAttributeNotFoundException.java create mode 100644 common/src/main/java/dev/cel/common/exceptions/CelBadFormatException.java rename runtime/src/main/java/dev/cel/runtime/standard/ArithmeticHelpers.java => common/src/main/java/dev/cel/common/exceptions/CelDivideByZeroException.java (59%) create mode 100644 common/src/main/java/dev/cel/common/exceptions/CelIndexOutOfBoundsException.java create mode 100644 common/src/main/java/dev/cel/common/exceptions/CelInvalidArgumentException.java create mode 100644 common/src/main/java/dev/cel/common/exceptions/CelNumericOverflowException.java rename common/src/main/java/dev/cel/common/{ => exceptions}/CelRuntimeException.java (75%) diff --git a/common/BUILD.bazel b/common/BUILD.bazel index 815d8a1da..75459597b 100644 --- a/common/BUILD.bazel +++ b/common/BUILD.bazel @@ -53,13 +53,6 @@ java_library( exports = ["//common/src/main/java/dev/cel/common:mutable_source"], ) -java_library( - name = "runtime_exception", - # used_by_android - visibility = ["//:internal"], - exports = ["//common/src/main/java/dev/cel/common:runtime_exception"], -) - java_library( name = "proto_json_adapter", exports = ["//common/src/main/java/dev/cel/common:proto_json_adapter"], diff --git a/common/exceptions/BUILD.bazel b/common/exceptions/BUILD.bazel new file mode 100644 index 000000000..7547ddc18 --- /dev/null +++ b/common/exceptions/BUILD.bazel @@ -0,0 +1,48 @@ +load("@rules_java//java:defs.bzl", "java_library") + +package( + default_applicable_licenses = ["//:license"], + default_visibility = ["//:internal"], +) + +java_library( + name = "runtime_exception", + # used_by_android + exports = ["//common/src/main/java/dev/cel/common/exceptions:runtime_exception"], +) + +java_library( + name = "attribute_not_found", + # used_by_android + exports = ["//common/src/main/java/dev/cel/common/exceptions:attribute_not_found"], +) + +java_library( + name = "divide_by_zero", + # used_by_android + exports = ["//common/src/main/java/dev/cel/common/exceptions:divide_by_zero"], +) + +java_library( + name = "index_out_of_bounds", + # used_by_android + exports = ["//common/src/main/java/dev/cel/common/exceptions:index_out_of_bounds"], +) + +java_library( + name = "bad_format", + # used_by_android + exports = ["//common/src/main/java/dev/cel/common/exceptions:bad_format"], +) + +java_library( + name = "numeric_overflow", + # used_by_android + exports = ["//common/src/main/java/dev/cel/common/exceptions:numeric_overflow"], +) + +java_library( + name = "invalid_argument", + # used_by_android + exports = ["//common/src/main/java/dev/cel/common/exceptions:invalid_argument"], +) diff --git a/common/src/main/java/dev/cel/common/BUILD.bazel b/common/src/main/java/dev/cel/common/BUILD.bazel index 7cd10f392..0050a2a7e 100644 --- a/common/src/main/java/dev/cel/common/BUILD.bazel +++ b/common/src/main/java/dev/cel/common/BUILD.bazel @@ -172,18 +172,6 @@ java_library( ], ) -java_library( - name = "runtime_exception", - srcs = ["CelRuntimeException.java"], - # used_by_android - tags = [ - ], - deps = [ - ":error_codes", - "//common/annotations", - ], -) - java_library( name = "mutable_ast", srcs = ["CelMutableAst.java"], @@ -205,7 +193,6 @@ java_library( ], deps = [ ":cel_source", - "//:auto_value", "//common/ast:mutable_expr", "@maven//:com_google_errorprone_error_prone_annotations", "@maven//:com_google_guava_guava", @@ -249,7 +236,6 @@ java_library( ":source", ":source_location", "//:auto_value", - "//common/annotations", "//common/ast", "//common/internal", "@maven//:com_google_errorprone_error_prone_annotations", @@ -360,8 +346,5 @@ java_library( srcs = ["Operator.java"], tags = [ ], - deps = [ - "//common/ast", - "@maven//:com_google_guava_guava", - ], + deps = ["@maven//:com_google_guava_guava"], ) diff --git a/common/src/main/java/dev/cel/common/CelException.java b/common/src/main/java/dev/cel/common/CelException.java index 9d80a9ba1..55c8623a4 100644 --- a/common/src/main/java/dev/cel/common/CelException.java +++ b/common/src/main/java/dev/cel/common/CelException.java @@ -27,11 +27,6 @@ public CelException(String message, Throwable cause) { super(message, cause); } - public CelException(String message, CelErrorCode errorCode) { - super(message); - this.errorCode = errorCode; - } - public CelException(String message, Throwable cause, CelErrorCode errorCode) { super(message, cause); this.errorCode = errorCode; diff --git a/common/src/main/java/dev/cel/common/exceptions/BUILD.bazel b/common/src/main/java/dev/cel/common/exceptions/BUILD.bazel new file mode 100644 index 000000000..b78034f6a --- /dev/null +++ b/common/src/main/java/dev/cel/common/exceptions/BUILD.bazel @@ -0,0 +1,99 @@ +load("@rules_java//java:defs.bzl", "java_library") + +package( + default_applicable_licenses = ["//:license"], + default_visibility = [ + "//common/exceptions:__pkg__", + "//publish:__pkg__", + ], +) + +java_library( + name = "runtime_exception", + srcs = ["CelRuntimeException.java"], + # used_by_android + tags = [ + ], + deps = [ + "//common:error_codes", + "//common/annotations", + ], +) + +java_library( + name = "attribute_not_found", + srcs = ["CelAttributeNotFoundException.java"], + # used_by_android + tags = [ + ], + deps = [ + "//common:error_codes", + "//common/annotations", + "//common/exceptions:runtime_exception", + ], +) + +java_library( + name = "divide_by_zero", + srcs = ["CelDivideByZeroException.java"], + # used_by_android + tags = [ + ], + deps = [ + "//common:error_codes", + "//common/annotations", + "//common/exceptions:runtime_exception", + ], +) + +java_library( + name = "index_out_of_bounds", + srcs = ["CelIndexOutOfBoundsException.java"], + # used_by_android + tags = [ + ], + deps = [ + "//common:error_codes", + "//common/annotations", + "//common/exceptions:runtime_exception", + ], +) + +java_library( + name = "bad_format", + srcs = ["CelBadFormatException.java"], + # used_by_android + tags = [ + ], + deps = [ + "//common:error_codes", + "//common/annotations", + "//common/exceptions:runtime_exception", + ], +) + +java_library( + name = "numeric_overflow", + srcs = ["CelNumericOverflowException.java"], + # used_by_android + tags = [ + ], + deps = [ + "//common:error_codes", + "//common/annotations", + "//common/exceptions:runtime_exception", + ], +) + +java_library( + name = "invalid_argument", + srcs = ["CelInvalidArgumentException.java"], + # used_by_android + tags = [ + ], + deps = [ + "//common:error_codes", + "//common/annotations", + "//common/exceptions:runtime_exception", + ], +) diff --git a/common/src/main/java/dev/cel/common/exceptions/CelAttributeNotFoundException.java b/common/src/main/java/dev/cel/common/exceptions/CelAttributeNotFoundException.java new file mode 100644 index 000000000..6204fd2fe --- /dev/null +++ b/common/src/main/java/dev/cel/common/exceptions/CelAttributeNotFoundException.java @@ -0,0 +1,56 @@ +// Copyright 2025 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.common.exceptions; + +import dev.cel.common.CelErrorCode; +import dev.cel.common.annotations.Internal; +import java.util.Arrays; +import java.util.Collection; + +/** Indicates an attempt to access a map or object using an invalid attribute or key. */ +@Internal +public final class CelAttributeNotFoundException extends CelRuntimeException { + + public static CelAttributeNotFoundException of(String message) { + return new CelAttributeNotFoundException(message); + } + + public static CelAttributeNotFoundException forMissingMapKey(String key) { + return new CelAttributeNotFoundException(String.format("key '%s' is not present in map.", key)); + } + + public static CelAttributeNotFoundException forFieldResolution(String... fields) { + return forFieldResolution(Arrays.asList(fields)); + } + + public static CelAttributeNotFoundException forFieldResolution(Collection fields) { + return new CelAttributeNotFoundException(formatErrorMessage(fields)); + } + + private static String formatErrorMessage(Collection fields) { + String maybePlural = ""; + if (fields.size() > 1) { + maybePlural = "s"; + } + + return String.format( + "Error resolving field%s '%s'. Field selections must be performed on messages or maps.", + maybePlural, String.join(", ", fields)); + } + + private CelAttributeNotFoundException(String message) { + super(message, CelErrorCode.ATTRIBUTE_NOT_FOUND); + } +} diff --git a/common/src/main/java/dev/cel/common/exceptions/CelBadFormatException.java b/common/src/main/java/dev/cel/common/exceptions/CelBadFormatException.java new file mode 100644 index 000000000..ba4db602a --- /dev/null +++ b/common/src/main/java/dev/cel/common/exceptions/CelBadFormatException.java @@ -0,0 +1,31 @@ +// Copyright 2025 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.common.exceptions; + +import dev.cel.common.CelErrorCode; +import dev.cel.common.annotations.Internal; + +/** Indicates that a data conversion failed due to a mismatch in the format specification. */ +@Internal +public final class CelBadFormatException extends CelRuntimeException { + + public CelBadFormatException(Throwable cause) { + super(cause, CelErrorCode.BAD_FORMAT); + } + + public CelBadFormatException(String errorMessage) { + super(errorMessage, CelErrorCode.BAD_FORMAT); + } +} diff --git a/runtime/src/main/java/dev/cel/runtime/standard/ArithmeticHelpers.java b/common/src/main/java/dev/cel/common/exceptions/CelDivideByZeroException.java similarity index 59% rename from runtime/src/main/java/dev/cel/runtime/standard/ArithmeticHelpers.java rename to common/src/main/java/dev/cel/common/exceptions/CelDivideByZeroException.java index 310e9401f..c507797c5 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/ArithmeticHelpers.java +++ b/common/src/main/java/dev/cel/common/exceptions/CelDivideByZeroException.java @@ -12,20 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -package dev.cel.runtime.standard; +package dev.cel.common.exceptions; import dev.cel.common.CelErrorCode; +import dev.cel.common.annotations.Internal; -final class ArithmeticHelpers { +/** Indicates that a division by zero occurred. */ +@Internal +public final class CelDivideByZeroException extends CelRuntimeException { - static CelErrorCode getArithmeticErrorCode(ArithmeticException e) { - String exceptionMessage = e.getMessage(); - // The two known cases for an arithmetic exception is divide by zero and overflow. - if (exceptionMessage.equals("/ by zero")) { - return CelErrorCode.DIVIDE_BY_ZERO; - } - return CelErrorCode.NUMERIC_OVERFLOW; + public CelDivideByZeroException() { + super("/ by zero", CelErrorCode.DIVIDE_BY_ZERO); } - private ArithmeticHelpers() {} + public CelDivideByZeroException(Throwable cause) { + super(cause, CelErrorCode.DIVIDE_BY_ZERO); + } } diff --git a/common/src/main/java/dev/cel/common/exceptions/CelIndexOutOfBoundsException.java b/common/src/main/java/dev/cel/common/exceptions/CelIndexOutOfBoundsException.java new file mode 100644 index 000000000..72a6cd1c0 --- /dev/null +++ b/common/src/main/java/dev/cel/common/exceptions/CelIndexOutOfBoundsException.java @@ -0,0 +1,27 @@ +// Copyright 2025 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.common.exceptions; + +import dev.cel.common.CelErrorCode; +import dev.cel.common.annotations.Internal; + +/** Indicates that a list index access was attempted using an index that is out of bounds. */ +@Internal +public final class CelIndexOutOfBoundsException extends CelRuntimeException { + + public CelIndexOutOfBoundsException(Object index) { + super("Index out of bounds: " + index, CelErrorCode.INDEX_OUT_OF_BOUNDS); + } +} diff --git a/common/src/main/java/dev/cel/common/exceptions/CelInvalidArgumentException.java b/common/src/main/java/dev/cel/common/exceptions/CelInvalidArgumentException.java new file mode 100644 index 000000000..41358bb79 --- /dev/null +++ b/common/src/main/java/dev/cel/common/exceptions/CelInvalidArgumentException.java @@ -0,0 +1,27 @@ +// Copyright 2025 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.common.exceptions; + +import dev.cel.common.CelErrorCode; +import dev.cel.common.annotations.Internal; + +/** Indicates that an invalid argument was supplied to a function. */ +@Internal +public final class CelInvalidArgumentException extends CelRuntimeException { + + public CelInvalidArgumentException(Throwable cause) { + super(cause, CelErrorCode.INVALID_ARGUMENT); + } +} diff --git a/common/src/main/java/dev/cel/common/exceptions/CelNumericOverflowException.java b/common/src/main/java/dev/cel/common/exceptions/CelNumericOverflowException.java new file mode 100644 index 000000000..78fbe807e --- /dev/null +++ b/common/src/main/java/dev/cel/common/exceptions/CelNumericOverflowException.java @@ -0,0 +1,34 @@ +// Copyright 2025 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.common.exceptions; + +import dev.cel.common.CelErrorCode; +import dev.cel.common.annotations.Internal; + +/** + * Indicates that a numeric overflow occurred due to arithmetic operations or conversions resulting + * in a value outside the representable range. + */ +@Internal +public final class CelNumericOverflowException extends CelRuntimeException { + + public CelNumericOverflowException(String message) { + super(message, CelErrorCode.NUMERIC_OVERFLOW); + } + + public CelNumericOverflowException(Throwable cause) { + super(cause, CelErrorCode.NUMERIC_OVERFLOW); + } +} diff --git a/common/src/main/java/dev/cel/common/CelRuntimeException.java b/common/src/main/java/dev/cel/common/exceptions/CelRuntimeException.java similarity index 75% rename from common/src/main/java/dev/cel/common/CelRuntimeException.java rename to common/src/main/java/dev/cel/common/exceptions/CelRuntimeException.java index 6f194c474..03e0700b1 100644 --- a/common/src/main/java/dev/cel/common/CelRuntimeException.java +++ b/common/src/main/java/dev/cel/common/exceptions/CelRuntimeException.java @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package dev.cel.common; +package dev.cel.common.exceptions; +import dev.cel.common.CelErrorCode; import dev.cel.common.annotations.Internal; /** @@ -21,15 +22,17 @@ * *

Note: This is not to be confused with the notion of CEL Runtime. Use {@code * CelEvaluationException} instead to signify an evaluation error. - * - *

TODO: Make this class abstract and define specific exception classes that - * corresponds to the CelErrorCode. */ @Internal -public class CelRuntimeException extends RuntimeException { +public abstract class CelRuntimeException extends RuntimeException { private final CelErrorCode errorCode; - public CelRuntimeException(Throwable cause, CelErrorCode errorCode) { + CelRuntimeException(String errorMessage, CelErrorCode errorCode) { + super(errorMessage); + this.errorCode = errorCode; + } + + CelRuntimeException(Throwable cause, CelErrorCode errorCode) { super(cause); this.errorCode = errorCode; } diff --git a/common/src/main/java/dev/cel/common/internal/BUILD.bazel b/common/src/main/java/dev/cel/common/internal/BUILD.bazel index 690b1cc75..c96a3dcfd 100644 --- a/common/src/main/java/dev/cel/common/internal/BUILD.bazel +++ b/common/src/main/java/dev/cel/common/internal/BUILD.bazel @@ -173,11 +173,9 @@ java_library( ":proto_lite_adapter", ":proto_message_factory", ":well_known_proto", - "//:auto_value", - "//common:error_codes", "//common:options", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:numeric_overflow", "//common/values", "//common/values:cel_byte_string", "@maven//:com_google_code_findbugs_annotations", @@ -194,11 +192,10 @@ java_library( ], deps = [ ":well_known_proto", - "//common:error_codes", "//common:options", "//common:proto_json_adapter", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:numeric_overflow", "//common/internal:proto_time_utils", "//common/values", "//common/values:cel_byte_string", @@ -440,9 +437,8 @@ java_library( tags = [ ], deps = [ - "//common:error_codes", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:bad_format", "@maven//:com_google_guava_guava", "@maven//:com_google_protobuf_protobuf_java", ], @@ -454,9 +450,8 @@ cel_android_library( tags = [ ], deps = [ - "//common:error_codes", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:bad_format", "@maven_android//:com_google_guava_guava", "@maven_android//:com_google_protobuf_protobuf_javalite", ], diff --git a/common/src/main/java/dev/cel/common/internal/DateTimeHelpers.java b/common/src/main/java/dev/cel/common/internal/DateTimeHelpers.java index 9abe39b4b..703fd2801 100644 --- a/common/src/main/java/dev/cel/common/internal/DateTimeHelpers.java +++ b/common/src/main/java/dev/cel/common/internal/DateTimeHelpers.java @@ -16,9 +16,8 @@ import com.google.common.base.Strings; import com.google.protobuf.Timestamp; -import dev.cel.common.CelErrorCode; -import dev.cel.common.CelRuntimeException; import dev.cel.common.annotations.Internal; +import dev.cel.common.exceptions.CelBadFormatException; import java.time.DateTimeException; import java.time.Duration; import java.time.Instant; @@ -184,7 +183,7 @@ private static ZoneId timeZone(String tz) { try { int ind = tz.indexOf(":"); if (ind == -1) { - throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException(e); } int hourOffset = Integer.parseInt(tz.substring(0, ind)); @@ -199,7 +198,7 @@ private static ZoneId timeZone(String tz) { return ZoneId.of(formattedOffset); } catch (DateTimeException e2) { - throw new CelRuntimeException(e2, CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException(e2); } } } diff --git a/common/src/main/java/dev/cel/common/internal/ProtoAdapter.java b/common/src/main/java/dev/cel/common/internal/ProtoAdapter.java index cd4be2f5e..3c3382ef2 100644 --- a/common/src/main/java/dev/cel/common/internal/ProtoAdapter.java +++ b/common/src/main/java/dev/cel/common/internal/ProtoAdapter.java @@ -31,10 +31,9 @@ import com.google.protobuf.MapEntry; import com.google.protobuf.Message; import com.google.protobuf.MessageOrBuilder; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; import dev.cel.common.annotations.Internal; +import dev.cel.common.exceptions.CelNumericOverflowException; import dev.cel.common.values.CelByteString; import dev.cel.common.values.NullValue; import java.util.ArrayList; @@ -361,7 +360,7 @@ private static int intCheckedCast(long value) { try { return Ints.checkedCast(value); } catch (IllegalArgumentException e) { - throw new CelRuntimeException(e, CelErrorCode.NUMERIC_OVERFLOW); + throw new CelNumericOverflowException(e); } } @@ -369,7 +368,7 @@ private static int unsignedIntCheckedCast(long value) { try { return UnsignedInts.checkedCast(value); } catch (IllegalArgumentException e) { - throw new CelRuntimeException(e, CelErrorCode.NUMERIC_OVERFLOW); + throw new CelNumericOverflowException(e); } } } diff --git a/common/src/main/java/dev/cel/common/internal/ProtoLiteAdapter.java b/common/src/main/java/dev/cel/common/internal/ProtoLiteAdapter.java index e05d92f68..3b13ecea1 100644 --- a/common/src/main/java/dev/cel/common/internal/ProtoLiteAdapter.java +++ b/common/src/main/java/dev/cel/common/internal/ProtoLiteAdapter.java @@ -42,11 +42,10 @@ import com.google.protobuf.UInt32Value; import com.google.protobuf.UInt64Value; import com.google.protobuf.Value; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; import dev.cel.common.CelProtoJsonAdapter; -import dev.cel.common.CelRuntimeException; import dev.cel.common.annotations.Internal; +import dev.cel.common.exceptions.CelNumericOverflowException; import dev.cel.common.values.CelByteString; import java.time.Instant; import java.util.Map; @@ -284,14 +283,14 @@ private Message adaptValueToUint32(Object value) { try { return UInt32Value.of(unsignedIntCheckedCast((Long) value)); } catch (IllegalArgumentException e) { - throw new CelRuntimeException(e, CelErrorCode.NUMERIC_OVERFLOW); + throw new CelNumericOverflowException(e); } } if (value instanceof UnsignedLong) { try { return UInt32Value.of(unsignedIntCheckedCast(((UnsignedLong) value).longValue())); } catch (IllegalArgumentException e) { - throw new CelRuntimeException(e, CelErrorCode.NUMERIC_OVERFLOW); + throw new CelNumericOverflowException(e); } } @@ -316,7 +315,7 @@ private static int intCheckedCast(long value) { try { return Ints.checkedCast(value); } catch (IllegalArgumentException e) { - throw new CelRuntimeException(e, CelErrorCode.NUMERIC_OVERFLOW); + throw new CelNumericOverflowException(e); } } @@ -324,7 +323,7 @@ private static int unsignedIntCheckedCast(long value) { try { return UnsignedInts.checkedCast(value); } catch (IllegalArgumentException e) { - throw new CelRuntimeException(e, CelErrorCode.NUMERIC_OVERFLOW); + throw new CelNumericOverflowException(e); } } diff --git a/extensions/src/main/java/dev/cel/extensions/BUILD.bazel b/extensions/src/main/java/dev/cel/extensions/BUILD.bazel index 9b897cf84..ed2d19d6f 100644 --- a/extensions/src/main/java/dev/cel/extensions/BUILD.bazel +++ b/extensions/src/main/java/dev/cel/extensions/BUILD.bazel @@ -123,6 +123,7 @@ java_library( "//common:compiler_common", "//common:options", "//common/ast", + "//common/exceptions:numeric_overflow", "//common/internal:comparison_functions", "//common/types", "//compiler:compiler_builder", diff --git a/extensions/src/main/java/dev/cel/extensions/CelMathExtensions.java b/extensions/src/main/java/dev/cel/extensions/CelMathExtensions.java index 1e318aedc..e74177bf1 100644 --- a/extensions/src/main/java/dev/cel/extensions/CelMathExtensions.java +++ b/extensions/src/main/java/dev/cel/extensions/CelMathExtensions.java @@ -32,6 +32,7 @@ import dev.cel.common.ast.CelConstant; import dev.cel.common.ast.CelExpr; import dev.cel.common.ast.CelExpr.ExprKind.Kind; +import dev.cel.common.exceptions.CelNumericOverflowException; import dev.cel.common.internal.ComparisonFunctions; import dev.cel.common.types.ListType; import dev.cel.common.types.SimpleType; @@ -216,8 +217,7 @@ enum Function { "math_@max_int_double", Long.class, Double.class, CelMathExtensions::maxPair), CelFunctionBinding.from( "math_@max_double_int", Double.class, Long.class, CelMathExtensions::maxPair), - CelFunctionBinding.from( - "math_@max_list_dyn", List.class, CelMathExtensions::maxList)), + CelFunctionBinding.from("math_@max_list_dyn", List.class, CelMathExtensions::maxList)), ImmutableSet.of( CelFunctionBinding.from("math_@max_uint", Long.class, x -> x), CelFunctionBinding.from( @@ -640,8 +640,7 @@ enum Function { ImmutableSet.of( CelFunctionBinding.from( "math_sqrt_double", Double.class, CelMathExtensions::sqrtDouble), - CelFunctionBinding.from( - "math_sqrt_int", Long.class, CelMathExtensions::sqrtInt), + CelFunctionBinding.from("math_sqrt_int", Long.class, CelMathExtensions::sqrtInt), CelFunctionBinding.from( "math_sqrt_uint", UnsignedLong.class, CelMathExtensions::sqrtUint))); @@ -856,7 +855,7 @@ private static Comparable minPair(Comparable x, Comparable y) { private static long absExact(long x) { if (x == Long.MIN_VALUE) { // The only case where standard Math.abs overflows silently - throw new ArithmeticException("integer overflow"); + throw new CelNumericOverflowException("integer overflow"); } return Math.abs(x); } diff --git a/extensions/src/test/java/dev/cel/extensions/BUILD.bazel b/extensions/src/test/java/dev/cel/extensions/BUILD.bazel index 45d48aeca..d5155f662 100644 --- a/extensions/src/test/java/dev/cel/extensions/BUILD.bazel +++ b/extensions/src/test/java/dev/cel/extensions/BUILD.bazel @@ -14,7 +14,8 @@ java_library( "//common:compiler_common", "//common:container", "//common:options", - "//common/internal:proto_time_utils", + "//common/exceptions:divide_by_zero", + "//common/exceptions:index_out_of_bounds", "//common/types", "//common/types:type_providers", "//common/values", diff --git a/extensions/src/test/java/dev/cel/extensions/CelComprehensionsExtensionsTest.java b/extensions/src/test/java/dev/cel/extensions/CelComprehensionsExtensionsTest.java index 5318234b9..34696b688 100644 --- a/extensions/src/test/java/dev/cel/extensions/CelComprehensionsExtensionsTest.java +++ b/extensions/src/test/java/dev/cel/extensions/CelComprehensionsExtensionsTest.java @@ -24,6 +24,8 @@ import dev.cel.common.CelFunctionDecl; import dev.cel.common.CelOptions; import dev.cel.common.CelValidationException; +import dev.cel.common.exceptions.CelDivideByZeroException; +import dev.cel.common.exceptions.CelIndexOutOfBoundsException; import dev.cel.common.types.SimpleType; import dev.cel.common.types.TypeParamType; import dev.cel.compiler.CelCompiler; @@ -347,13 +349,13 @@ public void twoVarComprehension_keyCollision_runtimeError(String expr, String er } @Test - public void twoVarComprehension_arithematicException_runtimeError() throws Exception { + public void twoVarComprehension_arithmeticException_runtimeError() throws Exception { CelAbstractSyntaxTree ast = CEL_COMPILER.compile("[0].all(i, k, i/k < k)").getAst(); CelEvaluationException e = assertThrows(CelEvaluationException.class, () -> CEL_RUNTIME.createProgram(ast).eval()); - assertThat(e).hasCauseThat().isInstanceOf(ArithmeticException.class); + assertThat(e).hasCauseThat().isInstanceOf(CelDivideByZeroException.class); assertThat(e).hasCauseThat().hasMessageThat().contains("/ by zero"); } @@ -364,7 +366,7 @@ public void twoVarComprehension_outOfBounds_runtimeError() throws Exception { CelEvaluationException e = assertThrows(CelEvaluationException.class, () -> CEL_RUNTIME.createProgram(ast).eval()); - assertThat(e).hasCauseThat().isInstanceOf(IndexOutOfBoundsException.class); + assertThat(e).hasCauseThat().isInstanceOf(CelIndexOutOfBoundsException.class); assertThat(e).hasCauseThat().hasMessageThat().contains("Index out of bounds: 1"); } } diff --git a/runtime/src/main/java/dev/cel/runtime/BUILD.bazel b/runtime/src/main/java/dev/cel/runtime/BUILD.bazel index 847092cc3..178bb1728 100644 --- a/runtime/src/main/java/dev/cel/runtime/BUILD.bazel +++ b/runtime/src/main/java/dev/cel/runtime/BUILD.bazel @@ -98,10 +98,9 @@ java_library( ":runtime_type_provider", "//common:cel_descriptor_util", "//common:cel_descriptors", - "//common:error_codes", "//common:options", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:attribute_not_found", "//common/internal:cel_descriptor_pools", "//common/internal:default_message_factory", "//common/internal:dynamic_proto", @@ -298,9 +297,9 @@ java_library( "//common:cel_ast", "//common:error_codes", "//common:options", - "//common:runtime_exception", "//common/annotations", "//common/ast", + "//common/exceptions:runtime_exception", "//common/types", "//common/types:type_providers", "//common/values:cel_byte_string", @@ -308,7 +307,6 @@ java_library( "@maven//:com_google_errorprone_error_prone_annotations", "@maven//:com_google_guava_guava", "@maven//:com_google_protobuf_protobuf_java", - "@maven//:org_jspecify_jspecify", ], ) @@ -337,9 +335,9 @@ cel_android_library( "//common:cel_ast_android", "//common:error_codes", "//common:options", - "//common:runtime_exception", "//common/annotations", "//common/ast:ast_android", + "//common/exceptions:runtime_exception", "//common/types:type_providers_android", "//common/types:types_android", "//common/values:cel_byte_string", @@ -360,10 +358,9 @@ java_library( ], deps = [ ":runtime_helpers", - "//common:error_codes", "//common:options", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:attribute_not_found", "//common/internal:comparison_functions", "@maven//:com_google_errorprone_error_prone_annotations", "@maven//:com_google_guava_guava", @@ -378,10 +375,9 @@ cel_android_library( ], deps = [ ":runtime_helpers_android", - "//common:error_codes", "//common:options", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:attribute_not_found", "//common/internal:comparison_functions_android", "@maven//:com_google_errorprone_error_prone_annotations", "@maven_android//:com_google_guava_guava", @@ -416,10 +412,11 @@ cel_android_library( ], deps = [ ":concatenated_list_view", - "//common:error_codes", "//common:options", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:divide_by_zero", + "//common/exceptions:index_out_of_bounds", + "//common/exceptions:numeric_overflow", "//common/internal:converter", "//common/values:values_android", "@maven//:com_google_errorprone_error_prone_annotations", @@ -439,10 +436,11 @@ java_library( ], deps = [ ":concatenated_list_view", - "//common:error_codes", "//common:options", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:divide_by_zero", + "//common/exceptions:index_out_of_bounds", + "//common/exceptions:numeric_overflow", "//common/internal:converter", "//common/values", "@maven//:com_google_errorprone_error_prone_annotations", @@ -558,8 +556,8 @@ java_library( ":evaluation_exception", ":metadata", "//common:error_codes", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:runtime_exception", "//common/internal:safe_string_formatter", "@maven//:com_google_errorprone_error_prone_annotations", "@maven//:org_jspecify_jspecify", @@ -1029,9 +1027,8 @@ java_library( deps = [ ":runtime_type_provider", ":unknown_attributes", - "//common:error_codes", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:attribute_not_found", "//common/values", "//common/values:base_proto_cel_value_converter", "//common/values:base_proto_message_value_provider", @@ -1050,9 +1047,8 @@ cel_android_library( deps = [ ":runtime_type_provider_android", ":unknown_attributes_android", - "//common:error_codes", - "//common:runtime_exception", "//common/annotations", + "//common/exceptions:attribute_not_found", "//common/values:base_proto_cel_value_converter_android", "//common/values:base_proto_message_value_provider_android", "//common/values:cel_value_android", diff --git a/runtime/src/main/java/dev/cel/runtime/CelEvaluationExceptionBuilder.java b/runtime/src/main/java/dev/cel/runtime/CelEvaluationExceptionBuilder.java index 6aaed4da7..986788bac 100644 --- a/runtime/src/main/java/dev/cel/runtime/CelEvaluationExceptionBuilder.java +++ b/runtime/src/main/java/dev/cel/runtime/CelEvaluationExceptionBuilder.java @@ -16,8 +16,8 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import dev.cel.common.CelErrorCode; -import dev.cel.common.CelRuntimeException; import dev.cel.common.annotations.Internal; +import dev.cel.common.exceptions.CelRuntimeException; import dev.cel.common.internal.SafeStringFormatter; import org.jspecify.annotations.Nullable; @@ -83,10 +83,15 @@ public static CelEvaluationExceptionBuilder newBuilder(String message, Object... */ @Internal public static CelEvaluationExceptionBuilder newBuilder(CelRuntimeException celRuntimeException) { - Throwable cause = celRuntimeException.getCause(); - return new CelEvaluationExceptionBuilder(cause.getMessage()) - .setCause(cause) - .setErrorCode(celRuntimeException.getErrorCode()); + // Intercept the cause to prevent including the cause's class name in the exception message. + String message = + celRuntimeException.getCause() == null + ? celRuntimeException.getMessage() + : celRuntimeException.getCause().getMessage(); + + return new CelEvaluationExceptionBuilder(message) + .setErrorCode(celRuntimeException.getErrorCode()) + .setCause(celRuntimeException); } private CelEvaluationExceptionBuilder(String message) { diff --git a/runtime/src/main/java/dev/cel/runtime/CelValueRuntimeTypeProvider.java b/runtime/src/main/java/dev/cel/runtime/CelValueRuntimeTypeProvider.java index 989d3b7be..e071289ca 100644 --- a/runtime/src/main/java/dev/cel/runtime/CelValueRuntimeTypeProvider.java +++ b/runtime/src/main/java/dev/cel/runtime/CelValueRuntimeTypeProvider.java @@ -18,9 +18,8 @@ import com.google.errorprone.annotations.Immutable; import com.google.protobuf.MessageLite; -import dev.cel.common.CelErrorCode; -import dev.cel.common.CelRuntimeException; import dev.cel.common.annotations.Internal; +import dev.cel.common.exceptions.CelAttributeNotFoundException; import dev.cel.common.values.BaseProtoCelValueConverter; import dev.cel.common.values.BaseProtoMessageValueProvider; import dev.cel.common.values.CelValue; @@ -82,9 +81,7 @@ public Object selectField(Object message, String fieldName) { return map.get(fieldName); } - throw new CelRuntimeException( - new IllegalArgumentException(String.format("key '%s' is not present in map.", fieldName)), - CelErrorCode.ATTRIBUTE_NOT_FOUND); + throw CelAttributeNotFoundException.forMissingMapKey(fieldName); } SelectableValue selectableValue = getSelectableValueOrThrow(message, fieldName); @@ -142,13 +139,7 @@ private Object maybeUnwrapCelValue(Object object) { } private static void throwInvalidFieldSelection(String fieldName) { - throw new CelRuntimeException( - new IllegalArgumentException( - String.format( - "Error resolving field '%s'. Field selections must be performed on messages or" - + " maps.", - fieldName)), - CelErrorCode.ATTRIBUTE_NOT_FOUND); + throw CelAttributeNotFoundException.forFieldResolution(fieldName); } private CelValueRuntimeTypeProvider( diff --git a/runtime/src/main/java/dev/cel/runtime/DefaultInterpreter.java b/runtime/src/main/java/dev/cel/runtime/DefaultInterpreter.java index 546290a4e..fac990d61 100644 --- a/runtime/src/main/java/dev/cel/runtime/DefaultInterpreter.java +++ b/runtime/src/main/java/dev/cel/runtime/DefaultInterpreter.java @@ -31,7 +31,6 @@ import dev.cel.common.CelAbstractSyntaxTree; import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; import dev.cel.common.ast.CelConstant; import dev.cel.common.ast.CelExpr; import dev.cel.common.ast.CelExpr.CelCall; @@ -42,6 +41,7 @@ import dev.cel.common.ast.CelExpr.CelStruct; import dev.cel.common.ast.CelExpr.ExprKind; import dev.cel.common.ast.CelReference; +import dev.cel.common.exceptions.CelRuntimeException; import dev.cel.common.types.CelKind; import dev.cel.common.types.CelType; import dev.cel.common.types.TypeType; diff --git a/runtime/src/main/java/dev/cel/runtime/DescriptorMessageProvider.java b/runtime/src/main/java/dev/cel/runtime/DescriptorMessageProvider.java index ab6934e01..f2ea85b9b 100644 --- a/runtime/src/main/java/dev/cel/runtime/DescriptorMessageProvider.java +++ b/runtime/src/main/java/dev/cel/runtime/DescriptorMessageProvider.java @@ -21,10 +21,9 @@ import com.google.protobuf.Message; import com.google.protobuf.MessageOrBuilder; import com.google.protobuf.NullValue; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; import dev.cel.common.annotations.Internal; +import dev.cel.common.exceptions.CelAttributeNotFoundException; import dev.cel.common.internal.DynamicProto; import dev.cel.common.internal.ProtoAdapter; import dev.cel.common.internal.ProtoMessageFactory; @@ -79,10 +78,8 @@ public DescriptorMessageProvider(ProtoMessageFactory protoMessageFactory, CelOpt .newBuilder(messageName) .orElseThrow( () -> - new CelRuntimeException( - new IllegalArgumentException( - String.format("cannot resolve '%s' as a message", messageName)), - CelErrorCode.ATTRIBUTE_NOT_FOUND)); + CelAttributeNotFoundException.of( + String.format("cannot resolve '%s' as a message", messageName))); try { Descriptor descriptor = builder.getDescriptorForType(); @@ -122,10 +119,7 @@ public DescriptorMessageProvider(ProtoMessageFactory protoMessageFactory, CelOpt if (isOptionalMessage) { return Optional.empty(); } else { - throw new CelRuntimeException( - new IllegalArgumentException( - String.format("key '%s' is not present in map.", fieldName)), - CelErrorCode.ATTRIBUTE_NOT_FOUND); + throw CelAttributeNotFoundException.forMissingMapKey(fieldName); } } @@ -197,13 +191,7 @@ private FieldDescriptor findField(Descriptor descriptor, String fieldName) { private static MessageOrBuilder assertFullProtoMessage(Object candidate, String fieldName) { if (!(candidate instanceof MessageOrBuilder)) { // This can happen when the field selection is done on dyn, and it is not a message. - throw new CelRuntimeException( - new IllegalArgumentException( - String.format( - "Error resolving field '%s'. Field selections must be performed on messages or" - + " maps.", - fieldName)), - CelErrorCode.ATTRIBUTE_NOT_FOUND); + throw CelAttributeNotFoundException.forFieldResolution(fieldName); } return (MessageOrBuilder) candidate; } diff --git a/runtime/src/main/java/dev/cel/runtime/RuntimeEquality.java b/runtime/src/main/java/dev/cel/runtime/RuntimeEquality.java index d0b2fcd6b..2044a2518 100644 --- a/runtime/src/main/java/dev/cel/runtime/RuntimeEquality.java +++ b/runtime/src/main/java/dev/cel/runtime/RuntimeEquality.java @@ -17,10 +17,9 @@ import com.google.common.primitives.UnsignedLong; import com.google.errorprone.annotations.Immutable; import com.google.protobuf.MessageLiteOrBuilder; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; import dev.cel.common.annotations.Internal; +import dev.cel.common.exceptions.CelAttributeNotFoundException; import dev.cel.common.internal.ComparisonFunctions; import java.util.Iterator; import java.util.List; @@ -67,8 +66,8 @@ public B indexMap(Map map, A index) { if (value.isPresent()) { return (B) value.get(); } - throw new CelRuntimeException( - new IndexOutOfBoundsException(index.toString()), CelErrorCode.ATTRIBUTE_NOT_FOUND); + + throw CelAttributeNotFoundException.of(index.toString()); } /** Determine whether the {@code map} contains the given {@code key}. */ diff --git a/runtime/src/main/java/dev/cel/runtime/RuntimeHelpers.java b/runtime/src/main/java/dev/cel/runtime/RuntimeHelpers.java index 25f01ef59..0ee7824b7 100644 --- a/runtime/src/main/java/dev/cel/runtime/RuntimeHelpers.java +++ b/runtime/src/main/java/dev/cel/runtime/RuntimeHelpers.java @@ -23,10 +23,11 @@ import com.google.protobuf.Duration; import com.google.protobuf.MessageLiteOrBuilder; import com.google.re2j.Pattern; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; import dev.cel.common.annotations.Internal; +import dev.cel.common.exceptions.CelDivideByZeroException; +import dev.cel.common.exceptions.CelIndexOutOfBoundsException; +import dev.cel.common.exceptions.CelNumericOverflowException; import dev.cel.common.internal.Converter; import dev.cel.common.values.NullValue; import java.time.format.DateTimeParseException; @@ -116,17 +117,11 @@ public static A indexList(List list, Number index) { if (index instanceof Double) { return doubleToLongLossless(index.doubleValue()) .map(v -> indexList(list, v)) - .orElseThrow( - () -> - new CelRuntimeException( - new IndexOutOfBoundsException("Index out of bounds: " + index.doubleValue()), - CelErrorCode.INDEX_OUT_OF_BOUNDS)); + .orElseThrow(() -> new CelIndexOutOfBoundsException(index.doubleValue())); } int castIndex = Ints.checkedCast(index.longValue()); if (castIndex < 0 || castIndex >= list.size()) { - throw new CelRuntimeException( - new IndexOutOfBoundsException("Index out of bounds: " + castIndex), - CelErrorCode.INDEX_OUT_OF_BOUNDS); + throw new CelIndexOutOfBoundsException(castIndex); } return list.get(castIndex); } @@ -145,7 +140,7 @@ public static long int64Add(long x, long y, CelOptions celOptions) { public static long int64Divide(long x, long y, CelOptions celOptions) { if (celOptions.errorOnIntWrap() && x == Long.MIN_VALUE && y == -1) { - throw new ArithmeticException("most negative number wraps"); + throw new CelNumericOverflowException("most negative number wraps"); } return x / y; } @@ -186,13 +181,13 @@ public static long uint64Add(long x, long y, CelOptions celOptions) { if (celOptions.errorOnIntWrap()) { if (x < 0 && y < 0) { // Both numbers are in the upper half of the range, so it must overflow. - throw new ArithmeticException("range overflow on unsigned addition"); + throw new CelNumericOverflowException("range overflow on unsigned addition"); } long z = x + y; if ((x < 0 || y < 0) && z >= 0) { // Only one number is in the upper half of the range. It overflows if the result // is not in the upper half. - throw new ArithmeticException("range overflow on unsigned addition"); + throw new CelNumericOverflowException("range overflow on unsigned addition"); } return z; } @@ -201,7 +196,7 @@ public static long uint64Add(long x, long y, CelOptions celOptions) { public static UnsignedLong uint64Add(UnsignedLong x, UnsignedLong y) { if (x.compareTo(UnsignedLong.MAX_VALUE.minus(y)) > 0) { - throw new ArithmeticException("range overflow on unsigned addition"); + throw new CelNumericOverflowException("range overflow on unsigned addition"); } return x.plus(y); } @@ -228,7 +223,7 @@ public static long uint64Divide(long x, long y, CelOptions celOptions) { ? UnsignedLongs.divide(x, y) : UnsignedLong.valueOf(x).dividedBy(UnsignedLong.valueOf(y)).longValue(); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, CelErrorCode.DIVIDE_BY_ZERO); + throw new CelDivideByZeroException(e); } } @@ -240,8 +235,7 @@ static long uint64Divide(long x, long y) { public static UnsignedLong uint64Divide(UnsignedLong x, UnsignedLong y) { if (y.equals(UnsignedLong.ZERO)) { - throw new CelRuntimeException( - new ArithmeticException("/ by zero"), CelErrorCode.DIVIDE_BY_ZERO); + throw new CelDivideByZeroException(); } return x.dividedBy(y); } @@ -252,14 +246,13 @@ public static long uint64Mod(long x, long y, CelOptions celOptions) { ? UnsignedLongs.remainder(x, y) : UnsignedLong.valueOf(x).mod(UnsignedLong.valueOf(y)).longValue(); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, CelErrorCode.DIVIDE_BY_ZERO); + throw new CelDivideByZeroException(e); } } public static UnsignedLong uint64Mod(UnsignedLong x, UnsignedLong y) { if (y.equals(UnsignedLong.ZERO)) { - throw new CelRuntimeException( - new ArithmeticException("/ by zero"), CelErrorCode.DIVIDE_BY_ZERO); + throw new CelDivideByZeroException(); } return x.mod(y); } @@ -276,7 +269,7 @@ public static long uint64Multiply(long x, long y, CelOptions celOptions) { ? x * y : UnsignedLong.valueOf(x).times(UnsignedLong.valueOf(y)).longValue(); if (celOptions.errorOnIntWrap() && y != 0 && Long.divideUnsigned(z, y) != x) { - throw new ArithmeticException("multiply out of unsigned integer range"); + throw new CelNumericOverflowException("multiply out of unsigned integer range"); } return z; } @@ -289,7 +282,7 @@ static long uint64Multiply(long x, long y) { public static UnsignedLong uint64Multiply(UnsignedLong x, UnsignedLong y) { if (!y.equals(UnsignedLong.ZERO) && x.compareTo(UnsignedLong.MAX_VALUE.dividedBy(y)) > 0) { - throw new ArithmeticException("multiply out of unsigned integer range"); + throw new CelNumericOverflowException("multiply out of unsigned integer range"); } return x.times(y); } @@ -299,7 +292,7 @@ public static long uint64Subtract(long x, long y, CelOptions celOptions) { // Throw an overflow error if x < y, as unsigned longs. This happens if y has its high // bit set and x does not, or if they have the same high bit and x < y as signed longs. if ((x < 0 && y < 0 && x < y) || (x >= 0 && y >= 0 && x < y) || (x >= 0 && y < 0)) { - throw new ArithmeticException("unsigned subtraction underflow"); + throw new CelNumericOverflowException("unsigned subtraction underflow"); } // fallthrough } @@ -310,7 +303,7 @@ public static UnsignedLong uint64Subtract(UnsignedLong x, UnsignedLong y) { // Throw an overflow error if x < y, as unsigned longs. This happens if y has its high // bit set and x does not, or if they have the same high bit and x < y as signed longs. if (x.compareTo(y) < 0) { - throw new ArithmeticException("unsigned subtraction underflow"); + throw new CelNumericOverflowException("unsigned subtraction underflow"); } return x.minus(y); } diff --git a/runtime/src/main/java/dev/cel/runtime/planner/BUILD.bazel b/runtime/src/main/java/dev/cel/runtime/planner/BUILD.bazel index 3ad0c0173..ab246a975 100644 --- a/runtime/src/main/java/dev/cel/runtime/planner/BUILD.bazel +++ b/runtime/src/main/java/dev/cel/runtime/planner/BUILD.bazel @@ -52,7 +52,7 @@ java_library( srcs = ["PlannedProgram.java"], deps = [ "//:auto_value", - "//common:runtime_exception", + "//common/exceptions:runtime_exception", "//common/values", "//runtime:activation", "//runtime:evaluation_exception", diff --git a/runtime/src/main/java/dev/cel/runtime/planner/PlannedProgram.java b/runtime/src/main/java/dev/cel/runtime/planner/PlannedProgram.java index 2c0d402c2..9bcdb6a76 100644 --- a/runtime/src/main/java/dev/cel/runtime/planner/PlannedProgram.java +++ b/runtime/src/main/java/dev/cel/runtime/planner/PlannedProgram.java @@ -16,7 +16,7 @@ import com.google.auto.value.AutoValue; import com.google.errorprone.annotations.Immutable; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelRuntimeException; import dev.cel.common.values.ErrorValue; import dev.cel.runtime.Activation; import dev.cel.runtime.CelEvaluationException; diff --git a/runtime/src/main/java/dev/cel/runtime/standard/AddOperator.java b/runtime/src/main/java/dev/cel/runtime/standard/AddOperator.java index 783ddd81a..84f4e2050 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/AddOperator.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/AddOperator.java @@ -14,15 +14,13 @@ package dev.cel.runtime.standard; -import static dev.cel.runtime.standard.ArithmeticHelpers.getArithmeticErrorCode; - import com.google.common.collect.ImmutableSet; import com.google.common.primitives.UnsignedLong; import com.google.protobuf.ByteString; import com.google.protobuf.Duration; import com.google.protobuf.Timestamp; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelNumericOverflowException; import dev.cel.common.internal.DateTimeHelpers; import dev.cel.common.internal.ProtoTimeUtils; import dev.cel.common.values.CelByteString; @@ -61,7 +59,7 @@ public enum AddOverload implements CelStandardOverload { try { return RuntimeHelpers.int64Add(x, y, celOptions); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelNumericOverflowException(e); } })), ADD_UINT64( @@ -75,7 +73,7 @@ public enum AddOverload implements CelStandardOverload { try { return RuntimeHelpers.uint64Add(x, y); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelNumericOverflowException(e); } }); } else { @@ -87,7 +85,7 @@ public enum AddOverload implements CelStandardOverload { try { return RuntimeHelpers.uint64Add(x, y, celOptions); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelNumericOverflowException(e); } }); } diff --git a/runtime/src/main/java/dev/cel/runtime/standard/BUILD.bazel b/runtime/src/main/java/dev/cel/runtime/standard/BUILD.bazel index 041d07dea..9f1bc708b 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/BUILD.bazel +++ b/runtime/src/main/java/dev/cel/runtime/standard/BUILD.bazel @@ -45,11 +45,10 @@ java_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_function", ":standard_overload", "//common:options", - "//common:runtime_exception", + "//common/exceptions:numeric_overflow", "//common/internal:date_time_helpers", "//common/internal:proto_time_utils", "//common/values:cel_byte_string", @@ -67,11 +66,10 @@ cel_android_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_function_android", ":standard_overload_android", "//common:options", - "//common:runtime_exception", + "//common/exceptions:numeric_overflow", "//common/internal:date_time_helpers_android", "//common/internal:proto_time_utils_android", "//common/values:cel_byte_string", @@ -89,11 +87,10 @@ java_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_function", ":standard_overload", "//common:options", - "//common:runtime_exception", + "//common/exceptions:numeric_overflow", "//common/internal:date_time_helpers", "//common/internal:proto_time_utils", "//runtime:function_binding", @@ -110,11 +107,10 @@ cel_android_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_function_android", ":standard_overload_android", "//common:options", - "//common:runtime_exception", + "//common/exceptions:numeric_overflow", "//common/internal:date_time_helpers_android", "//common/internal:proto_time_utils_android", "//runtime:function_binding_android", @@ -132,9 +128,8 @@ java_library( ], deps = [ ":standard_overload", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", "//common/internal:safe_string_formatter", "//runtime:function_binding", "//runtime:runtime_equality", @@ -151,9 +146,8 @@ cel_android_library( deps = [ ":standard_function_android", ":standard_overload_android", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", "//common/internal:safe_string_formatter", "//runtime:function_binding_android", "//runtime:runtime_equality_android", @@ -232,9 +226,8 @@ java_library( ], deps = [ ":standard_overload", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", "//runtime:function_binding", "//runtime:runtime_equality", "//runtime/standard:standard_function", @@ -250,9 +243,8 @@ cel_android_library( deps = [ ":standard_function_android", ":standard_overload_android", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", "//runtime:function_binding_android", "//runtime:runtime_equality_android", "@maven_android//:com_google_guava_guava", @@ -266,9 +258,8 @@ java_library( ], deps = [ ":standard_overload", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", "//runtime:function_binding", "//runtime:runtime_equality", "//runtime:runtime_helpers", @@ -286,9 +277,8 @@ cel_android_library( deps = [ ":standard_function_android", ":standard_overload_android", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", "//runtime:function_binding_android", "//runtime:runtime_equality_android", "//runtime:runtime_helpers_android", @@ -884,9 +874,9 @@ java_library( ], deps = [ ":standard_overload", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", + "//common/exceptions:numeric_overflow", "//common/internal:proto_time_utils", "//runtime:function_binding", "//runtime:runtime_equality", @@ -905,9 +895,9 @@ cel_android_library( deps = [ ":standard_function_android", ":standard_overload_android", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", + "//common/exceptions:numeric_overflow", "//common/internal:proto_time_utils_android", "//runtime:function_binding_android", "//runtime:runtime_equality_android", @@ -1034,9 +1024,8 @@ java_library( ], deps = [ ":standard_overload", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:invalid_argument", "//runtime:function_binding", "//runtime:runtime_equality", "//runtime:runtime_helpers", @@ -1053,9 +1042,8 @@ cel_android_library( deps = [ ":standard_function_android", ":standard_overload_android", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:invalid_argument", "//runtime:function_binding_android", "//runtime:runtime_equality_android", "//runtime:runtime_helpers_android", @@ -1069,10 +1057,9 @@ java_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_overload", "//common:options", - "//common:runtime_exception", + "//common/exceptions:divide_by_zero", "//runtime:function_binding", "//runtime:runtime_equality", "//runtime:runtime_helpers", @@ -1087,11 +1074,10 @@ cel_android_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_function_android", ":standard_overload_android", "//common:options", - "//common:runtime_exception", + "//common/exceptions:divide_by_zero", "//runtime:function_binding_android", "//runtime:runtime_equality_android", "//runtime:runtime_helpers_android", @@ -1105,10 +1091,9 @@ java_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_overload", "//common:options", - "//common:runtime_exception", + "//common/exceptions:numeric_overflow", "//runtime:function_binding", "//runtime:runtime_equality", "//runtime:runtime_helpers", @@ -1123,11 +1108,10 @@ cel_android_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_function_android", ":standard_overload_android", "//common:options", - "//common:runtime_exception", + "//common/exceptions:numeric_overflow", "//runtime:function_binding_android", "//runtime:runtime_equality_android", "//runtime:runtime_helpers_android", @@ -1141,10 +1125,9 @@ java_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_overload", "//common:options", - "//common:runtime_exception", + "//common/exceptions:divide_by_zero", "//runtime:function_binding", "//runtime:runtime_equality", "//runtime:runtime_helpers", @@ -1159,11 +1142,10 @@ cel_android_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_function_android", ":standard_overload_android", "//common:options", - "//common:runtime_exception", + "//common/exceptions:divide_by_zero", "//runtime:function_binding_android", "//runtime:runtime_equality_android", "//runtime:runtime_helpers_android", @@ -1177,10 +1159,9 @@ java_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_overload", "//common:options", - "//common:runtime_exception", + "//common/exceptions:numeric_overflow", "//runtime:function_binding", "//runtime:runtime_equality", "//runtime:runtime_helpers", @@ -1195,11 +1176,10 @@ cel_android_library( tags = [ ], deps = [ - ":arithmetic_helpers", ":standard_function_android", ":standard_overload_android", "//common:options", - "//common:runtime_exception", + "//common/exceptions:numeric_overflow", "//runtime:function_binding_android", "//runtime:runtime_equality_android", "//runtime:runtime_helpers_android", @@ -1308,9 +1288,8 @@ java_library( ], deps = [ ":standard_overload", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", "//common/internal:date_time_helpers", "//common/internal:proto_time_utils", "//common/values:cel_byte_string", @@ -1330,9 +1309,8 @@ cel_android_library( deps = [ ":standard_function_android", ":standard_overload_android", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", "//common/internal:date_time_helpers_android", "//common/internal:proto_time_utils_android", "//common/values:cel_byte_string", @@ -1350,9 +1328,8 @@ java_library( ], deps = [ ":standard_overload", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", "//common/internal:date_time_helpers", "//common/internal:proto_time_utils", "//runtime:function_binding", @@ -1371,9 +1348,8 @@ cel_android_library( deps = [ ":standard_function_android", ":standard_overload_android", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", "//common/internal:date_time_helpers_android", "//common/internal:proto_time_utils_android", "//runtime:function_binding_android", @@ -1390,9 +1366,9 @@ java_library( ], deps = [ ":standard_overload", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", + "//common/exceptions:numeric_overflow", "//runtime:function_binding", "//runtime:runtime_equality", "//runtime:runtime_helpers", @@ -1409,9 +1385,9 @@ cel_android_library( deps = [ ":standard_function_android", ":standard_overload_android", - "//common:error_codes", "//common:options", - "//common:runtime_exception", + "//common/exceptions:bad_format", + "//common/exceptions:numeric_overflow", "//runtime:function_binding_android", "//runtime:runtime_equality_android", "//runtime:runtime_helpers_android", @@ -1476,13 +1452,3 @@ cel_android_library( "@maven//:com_google_errorprone_error_prone_annotations", ], ) - -java_library( - name = "arithmetic_helpers", - srcs = ["ArithmeticHelpers.java"], - # used_by_android - visibility = ["//visibility:private"], - deps = [ - "//common:error_codes", - ], -) diff --git a/runtime/src/main/java/dev/cel/runtime/standard/BoolFunction.java b/runtime/src/main/java/dev/cel/runtime/standard/BoolFunction.java index 5d9d3919c..330fbe73f 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/BoolFunction.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/BoolFunction.java @@ -15,9 +15,8 @@ package dev.cel.runtime.standard; import com.google.common.collect.ImmutableSet; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelBadFormatException; import dev.cel.common.internal.SafeStringFormatter; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.RuntimeEquality; @@ -64,11 +63,9 @@ public enum BoolOverload implements CelStandardOverload { case "0": return false; default: - throw new CelRuntimeException( - new IllegalArgumentException( - SafeStringFormatter.format( - "Type conversion error from 'string' to 'bool': [%s]", str)), - CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException( + SafeStringFormatter.format( + "Type conversion error from 'string' to 'bool': [%s]", str)); } })); diff --git a/runtime/src/main/java/dev/cel/runtime/standard/DivideOperator.java b/runtime/src/main/java/dev/cel/runtime/standard/DivideOperator.java index b9fdad33c..6a45752dc 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/DivideOperator.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/DivideOperator.java @@ -14,12 +14,10 @@ package dev.cel.runtime.standard; -import static dev.cel.runtime.standard.ArithmeticHelpers.getArithmeticErrorCode; - import com.google.common.collect.ImmutableSet; import com.google.common.primitives.UnsignedLong; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelDivideByZeroException; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.RuntimeEquality; import dev.cel.runtime.RuntimeHelpers; @@ -57,7 +55,7 @@ public enum DivideOverload implements CelStandardOverload { try { return RuntimeHelpers.int64Divide(x, y, celOptions); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelDivideByZeroException(e); } })), DIVIDE_UINT64( diff --git a/runtime/src/main/java/dev/cel/runtime/standard/DoubleFunction.java b/runtime/src/main/java/dev/cel/runtime/standard/DoubleFunction.java index 508df1983..d2c4769b6 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/DoubleFunction.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/DoubleFunction.java @@ -16,9 +16,8 @@ import com.google.common.collect.ImmutableSet; import com.google.common.primitives.UnsignedLong; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelBadFormatException; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.RuntimeEquality; import java.util.Arrays; @@ -56,7 +55,7 @@ public enum DoubleOverload implements CelStandardOverload { try { return Double.parseDouble(arg); } catch (NumberFormatException e) { - throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException(e); } })), UINT64_TO_DOUBLE( diff --git a/runtime/src/main/java/dev/cel/runtime/standard/DurationFunction.java b/runtime/src/main/java/dev/cel/runtime/standard/DurationFunction.java index 72f96f785..b4fd184a6 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/DurationFunction.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/DurationFunction.java @@ -16,9 +16,8 @@ import com.google.common.collect.ImmutableSet; import com.google.protobuf.Duration; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelBadFormatException; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.RuntimeEquality; import dev.cel.runtime.RuntimeHelpers; @@ -62,13 +61,13 @@ public enum DurationOverload implements CelStandardOverload { try { return RuntimeHelpers.createJavaDurationFromString(d); } catch (IllegalArgumentException e) { - throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException(e); } } else { try { return RuntimeHelpers.createDurationFromString(d); } catch (IllegalArgumentException e) { - throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException(e); } } })), diff --git a/runtime/src/main/java/dev/cel/runtime/standard/IntFunction.java b/runtime/src/main/java/dev/cel/runtime/standard/IntFunction.java index fda307a9d..0c0768026 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/IntFunction.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/IntFunction.java @@ -17,9 +17,9 @@ import com.google.common.collect.ImmutableSet; import com.google.common.primitives.UnsignedLong; import com.google.protobuf.Timestamp; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelBadFormatException; +import dev.cel.common.exceptions.CelNumericOverflowException; import dev.cel.common.internal.ProtoTimeUtils; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.RuntimeEquality; @@ -56,9 +56,7 @@ public enum IntOverload implements CelStandardOverload { UnsignedLong.class, (UnsignedLong arg) -> { if (arg.compareTo(UnsignedLong.valueOf(Long.MAX_VALUE)) > 0) { - throw new CelRuntimeException( - new IllegalArgumentException("unsigned out of int range"), - CelErrorCode.NUMERIC_OVERFLOW); + throw new CelNumericOverflowException("unsigned out of int range"); } return arg.longValue(); }); @@ -68,9 +66,7 @@ public enum IntOverload implements CelStandardOverload { Long.class, (Long arg) -> { if (celOptions.errorOnIntWrap() && arg < 0) { - throw new CelRuntimeException( - new IllegalArgumentException("unsigned out of int range"), - CelErrorCode.NUMERIC_OVERFLOW); + throw new CelNumericOverflowException("unsigned out of int range"); } return arg; }); @@ -86,9 +82,7 @@ public enum IntOverload implements CelStandardOverload { return RuntimeHelpers.doubleToLongChecked(arg) .orElseThrow( () -> - new CelRuntimeException( - new IllegalArgumentException("double is out of range for int"), - CelErrorCode.NUMERIC_OVERFLOW)); + new CelNumericOverflowException("double is out of range for int")); } return arg.longValue(); })), @@ -101,7 +95,7 @@ public enum IntOverload implements CelStandardOverload { try { return Long.parseLong(arg); } catch (NumberFormatException e) { - throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException(e); } })), TIMESTAMP_TO_INT64( diff --git a/runtime/src/main/java/dev/cel/runtime/standard/MatchesFunction.java b/runtime/src/main/java/dev/cel/runtime/standard/MatchesFunction.java index 7c24f65a2..2d0a504b8 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/MatchesFunction.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/MatchesFunction.java @@ -15,9 +15,8 @@ package dev.cel.runtime.standard; import com.google.common.collect.ImmutableSet; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelInvalidArgumentException; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.RuntimeEquality; import dev.cel.runtime.RuntimeHelpers; @@ -51,7 +50,7 @@ public enum MatchesOverload implements CelStandardOverload { try { return RuntimeHelpers.matches(string, regexp, celOptions); } catch (RuntimeException e) { - throw new CelRuntimeException(e, CelErrorCode.INVALID_ARGUMENT); + throw new CelInvalidArgumentException(e); } })), // Duplicate receiver-style matches overload. @@ -65,7 +64,7 @@ public enum MatchesOverload implements CelStandardOverload { try { return RuntimeHelpers.matches(string, regexp, celOptions); } catch (RuntimeException e) { - throw new CelRuntimeException(e, CelErrorCode.INVALID_ARGUMENT); + throw new CelInvalidArgumentException(e); } })), ; diff --git a/runtime/src/main/java/dev/cel/runtime/standard/ModuloOperator.java b/runtime/src/main/java/dev/cel/runtime/standard/ModuloOperator.java index e7246851c..787d58de5 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/ModuloOperator.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/ModuloOperator.java @@ -14,12 +14,10 @@ package dev.cel.runtime.standard; -import static dev.cel.runtime.standard.ArithmeticHelpers.getArithmeticErrorCode; - import com.google.common.collect.ImmutableSet; import com.google.common.primitives.UnsignedLong; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelDivideByZeroException; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.RuntimeEquality; import dev.cel.runtime.RuntimeHelpers; @@ -53,7 +51,7 @@ public enum ModuloOverload implements CelStandardOverload { try { return x % y; } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelDivideByZeroException(e); } })), MODULO_UINT64( diff --git a/runtime/src/main/java/dev/cel/runtime/standard/MultiplyOperator.java b/runtime/src/main/java/dev/cel/runtime/standard/MultiplyOperator.java index 7e9e2f352..8a5ad1a56 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/MultiplyOperator.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/MultiplyOperator.java @@ -14,12 +14,10 @@ package dev.cel.runtime.standard; -import static dev.cel.runtime.standard.ArithmeticHelpers.getArithmeticErrorCode; - import com.google.common.collect.ImmutableSet; import com.google.common.primitives.UnsignedLong; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelNumericOverflowException; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.RuntimeEquality; import dev.cel.runtime.RuntimeHelpers; @@ -53,7 +51,7 @@ public enum MultiplyOverload implements CelStandardOverload { try { return RuntimeHelpers.int64Multiply(x, y, celOptions); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelNumericOverflowException(e); } })), MULTIPLY_DOUBLE( @@ -71,7 +69,7 @@ public enum MultiplyOverload implements CelStandardOverload { try { return RuntimeHelpers.uint64Multiply(x, y); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelNumericOverflowException(e); } }); } else { @@ -83,7 +81,7 @@ public enum MultiplyOverload implements CelStandardOverload { try { return RuntimeHelpers.uint64Multiply(x, y, celOptions); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelNumericOverflowException(e); } }); } diff --git a/runtime/src/main/java/dev/cel/runtime/standard/NegateOperator.java b/runtime/src/main/java/dev/cel/runtime/standard/NegateOperator.java index 2e3f094f5..5ff2a614d 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/NegateOperator.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/NegateOperator.java @@ -14,11 +14,9 @@ package dev.cel.runtime.standard; -import static dev.cel.runtime.standard.ArithmeticHelpers.getArithmeticErrorCode; - import com.google.common.collect.ImmutableSet; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelNumericOverflowException; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.RuntimeEquality; import dev.cel.runtime.RuntimeHelpers; @@ -51,7 +49,7 @@ public enum NegateOverload implements CelStandardOverload { try { return RuntimeHelpers.int64Negate(x, celOptions); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelNumericOverflowException(e); } })), NEGATE_DOUBLE( diff --git a/runtime/src/main/java/dev/cel/runtime/standard/StringFunction.java b/runtime/src/main/java/dev/cel/runtime/standard/StringFunction.java index c491bfe76..f19a4cd58 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/StringFunction.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/StringFunction.java @@ -20,9 +20,8 @@ import com.google.protobuf.ByteString; import com.google.protobuf.Duration; import com.google.protobuf.Timestamp; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelBadFormatException; import dev.cel.common.internal.DateTimeHelpers; import dev.cel.common.internal.ProtoTimeUtils; import dev.cel.common.values.CelByteString; @@ -69,10 +68,8 @@ public enum StringOverload implements CelStandardOverload { CelByteString.class, (byteStr) -> { if (!byteStr.isValidUtf8()) { - throw new CelRuntimeException( - new IllegalArgumentException( - "invalid UTF-8 in bytes, cannot convert to string"), - CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException( + "invalid UTF-8 in bytes, cannot convert to string"); } return byteStr.toStringUtf8(); }); @@ -82,10 +79,8 @@ public enum StringOverload implements CelStandardOverload { ByteString.class, (byteStr) -> { if (!byteStr.isValidUtf8()) { - throw new CelRuntimeException( - new IllegalArgumentException( - "invalid UTF-8 in bytes, cannot convert to string"), - CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException( + "invalid UTF-8 in bytes, cannot convert to string"); } return byteStr.toStringUtf8(); }); diff --git a/runtime/src/main/java/dev/cel/runtime/standard/SubtractOperator.java b/runtime/src/main/java/dev/cel/runtime/standard/SubtractOperator.java index 4b0ecd3ae..fe8b75230 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/SubtractOperator.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/SubtractOperator.java @@ -14,14 +14,12 @@ package dev.cel.runtime.standard; -import static dev.cel.runtime.standard.ArithmeticHelpers.getArithmeticErrorCode; - import com.google.common.collect.ImmutableSet; import com.google.common.primitives.UnsignedLong; import com.google.protobuf.Duration; import com.google.protobuf.Timestamp; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelNumericOverflowException; import dev.cel.common.internal.DateTimeHelpers; import dev.cel.common.internal.ProtoTimeUtils; import dev.cel.runtime.CelFunctionBinding; @@ -58,7 +56,7 @@ public enum SubtractOverload implements CelStandardOverload { try { return RuntimeHelpers.int64Subtract(x, y, celOptions); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelNumericOverflowException(e); } })), SUBTRACT_TIMESTAMP_TIMESTAMP( @@ -104,7 +102,7 @@ public enum SubtractOverload implements CelStandardOverload { try { return RuntimeHelpers.uint64Subtract(x, y); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelNumericOverflowException(e); } }); } else { @@ -116,7 +114,7 @@ public enum SubtractOverload implements CelStandardOverload { try { return RuntimeHelpers.uint64Subtract(x, y, celOptions); } catch (ArithmeticException e) { - throw new CelRuntimeException(e, getArithmeticErrorCode(e)); + throw new CelNumericOverflowException(e); } }); } diff --git a/runtime/src/main/java/dev/cel/runtime/standard/TimestampFunction.java b/runtime/src/main/java/dev/cel/runtime/standard/TimestampFunction.java index 34d3a1dc0..bffac3b06 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/TimestampFunction.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/TimestampFunction.java @@ -16,9 +16,8 @@ import com.google.common.collect.ImmutableSet; import com.google.protobuf.Timestamp; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelBadFormatException; import dev.cel.common.internal.DateTimeHelpers; import dev.cel.common.internal.ProtoTimeUtils; import dev.cel.runtime.CelFunctionBinding; @@ -56,14 +55,14 @@ public enum TimestampOverload implements CelStandardOverload { try { return DateTimeHelpers.parse(ts); } catch (DateTimeParseException e) { - throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException(e); } } else { try { return ProtoTimeUtils.parse(ts); } catch (ParseException e) { - throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException(e); } } })), diff --git a/runtime/src/main/java/dev/cel/runtime/standard/UintFunction.java b/runtime/src/main/java/dev/cel/runtime/standard/UintFunction.java index 89424e7fc..0548d8532 100644 --- a/runtime/src/main/java/dev/cel/runtime/standard/UintFunction.java +++ b/runtime/src/main/java/dev/cel/runtime/standard/UintFunction.java @@ -17,9 +17,9 @@ import com.google.common.collect.ImmutableSet; import com.google.common.primitives.UnsignedLong; import com.google.common.primitives.UnsignedLongs; -import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelBadFormatException; +import dev.cel.common.exceptions.CelNumericOverflowException; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.RuntimeEquality; import dev.cel.runtime.RuntimeHelpers; @@ -61,9 +61,7 @@ public enum UintOverload implements CelStandardOverload { Long.class, (Long arg) -> { if (celOptions.errorOnIntWrap() && arg < 0) { - throw new CelRuntimeException( - new IllegalArgumentException("int out of uint range"), - CelErrorCode.NUMERIC_OVERFLOW); + throw new CelNumericOverflowException("int out of uint range"); } return UnsignedLong.valueOf(arg); }); @@ -73,9 +71,7 @@ public enum UintOverload implements CelStandardOverload { Long.class, (Long arg) -> { if (celOptions.errorOnIntWrap() && arg < 0) { - throw new CelRuntimeException( - new IllegalArgumentException("int out of uint range"), - CelErrorCode.NUMERIC_OVERFLOW); + throw new CelNumericOverflowException("int out of uint range"); } return arg; }); @@ -91,10 +87,7 @@ public enum UintOverload implements CelStandardOverload { if (celOptions.errorOnIntWrap()) { return RuntimeHelpers.doubleToUnsignedChecked(arg) .orElseThrow( - () -> - new CelRuntimeException( - new IllegalArgumentException("double out of uint range"), - CelErrorCode.NUMERIC_OVERFLOW)); + () -> new CelNumericOverflowException("double out of uint range")); } return UnsignedLong.valueOf(BigDecimal.valueOf(arg).toBigInteger()); }); @@ -108,9 +101,8 @@ public enum UintOverload implements CelStandardOverload { .map(UnsignedLong::longValue) .orElseThrow( () -> - new CelRuntimeException( - new IllegalArgumentException("double out of uint range"), - CelErrorCode.NUMERIC_OVERFLOW)); + new CelNumericOverflowException( + "double out of uint range")); } return arg.longValue(); }); @@ -126,7 +118,7 @@ public enum UintOverload implements CelStandardOverload { try { return UnsignedLong.valueOf(arg); } catch (NumberFormatException e) { - throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException(e); } }); } else { @@ -137,7 +129,7 @@ public enum UintOverload implements CelStandardOverload { try { return UnsignedLongs.parseUnsignedLong(arg); } catch (NumberFormatException e) { - throw new CelRuntimeException(e, CelErrorCode.BAD_FORMAT); + throw new CelBadFormatException(e); } }); } diff --git a/runtime/src/test/java/dev/cel/runtime/BUILD.bazel b/runtime/src/test/java/dev/cel/runtime/BUILD.bazel index 1541e9c84..4c5a619f3 100644 --- a/runtime/src/test/java/dev/cel/runtime/BUILD.bazel +++ b/runtime/src/test/java/dev/cel/runtime/BUILD.bazel @@ -37,8 +37,11 @@ java_library( "//common:error_codes", "//common:options", "//common:proto_v1alpha1_ast", - "//common:runtime_exception", "//common/ast", + "//common/exceptions:bad_format", + "//common/exceptions:divide_by_zero", + "//common/exceptions:numeric_overflow", + "//common/exceptions:runtime_exception", "//common/internal:cel_descriptor_pools", "//common/internal:converter", "//common/internal:default_message_factory", diff --git a/runtime/src/test/java/dev/cel/runtime/CelEvaluationExceptionBuilderTest.java b/runtime/src/test/java/dev/cel/runtime/CelEvaluationExceptionBuilderTest.java index b3bc32e20..c073a8443 100644 --- a/runtime/src/test/java/dev/cel/runtime/CelEvaluationExceptionBuilderTest.java +++ b/runtime/src/test/java/dev/cel/runtime/CelEvaluationExceptionBuilderTest.java @@ -18,7 +18,8 @@ import com.google.testing.junit.testparameterinjector.TestParameterInjector; import dev.cel.common.CelErrorCode; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelBadFormatException; +import dev.cel.common.exceptions.CelRuntimeException; import org.junit.Test; import org.junit.runner.RunWith; @@ -87,15 +88,14 @@ public boolean hasPosition(long exprId) { @Test public void builder_fromCelRuntimeException() { IllegalStateException cause = new IllegalStateException("cause error message"); - CelRuntimeException celRuntimeException = - new CelRuntimeException(cause, CelErrorCode.BAD_FORMAT); + CelRuntimeException celRuntimeException = new CelBadFormatException(cause); CelEvaluationExceptionBuilder builder = CelEvaluationExceptionBuilder.newBuilder(celRuntimeException); CelEvaluationException e = builder.build(); assertThat(e).hasMessageThat().isEqualTo("evaluation error: cause error message"); - assertThat(e).hasCauseThat().isEqualTo(cause); + assertThat(e).hasCauseThat().isEqualTo(celRuntimeException); assertThat(e.getErrorCode()).isEqualTo(CelErrorCode.BAD_FORMAT); } } diff --git a/runtime/src/test/java/dev/cel/runtime/CelRuntimeLegacyImplTest.java b/runtime/src/test/java/dev/cel/runtime/CelRuntimeLegacyImplTest.java index c4a041f6a..fa3b5f4ae 100644 --- a/runtime/src/test/java/dev/cel/runtime/CelRuntimeLegacyImplTest.java +++ b/runtime/src/test/java/dev/cel/runtime/CelRuntimeLegacyImplTest.java @@ -18,6 +18,7 @@ import com.google.protobuf.Message; import dev.cel.common.CelException; +import dev.cel.common.exceptions.CelDivideByZeroException; import dev.cel.common.values.CelValueProvider; import dev.cel.compiler.CelCompiler; import dev.cel.compiler.CelCompilerFactory; @@ -39,7 +40,7 @@ public void evalException() throws CelException { CelRuntime runtime = CelRuntimeFactory.standardCelRuntimeBuilder().build(); CelRuntime.Program program = runtime.createProgram(compiler.compile("1/0").getAst()); CelEvaluationException e = Assert.assertThrows(CelEvaluationException.class, program::eval); - assertThat(e).hasCauseThat().isInstanceOf(ArithmeticException.class); + assertThat(e).hasCauseThat().isInstanceOf(CelDivideByZeroException.class); } @Test diff --git a/runtime/src/test/java/dev/cel/runtime/DescriptorMessageProviderTest.java b/runtime/src/test/java/dev/cel/runtime/DescriptorMessageProviderTest.java index 8866d1fa6..6ab1638b1 100644 --- a/runtime/src/test/java/dev/cel/runtime/DescriptorMessageProviderTest.java +++ b/runtime/src/test/java/dev/cel/runtime/DescriptorMessageProviderTest.java @@ -31,7 +31,7 @@ import dev.cel.common.CelDescriptors; import dev.cel.common.CelErrorCode; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelRuntimeException; import dev.cel.common.internal.CelDescriptorPool; import dev.cel.common.internal.DefaultDescriptorPool; import dev.cel.common.internal.DefaultMessageFactory; @@ -114,8 +114,8 @@ public void createMessage_missingDescriptorError() { () -> provider.createMessage( "google.api.tools.contract.test.MissingMessageTypes", ImmutableMap.of())); - assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class); assertThat(e.getErrorCode()).isEqualTo(CelErrorCode.ATTRIBUTE_NOT_FOUND); + assertThat(e).hasCauseThat().isNull(); } @Test @@ -159,8 +159,8 @@ public void selectField_mapKeyNotFound() { CelRuntimeException e = Assert.assertThrows( CelRuntimeException.class, () -> provider.selectField(ImmutableMap.of(), "hello")); - assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class); assertThat(e.getErrorCode()).isEqualTo(CelErrorCode.ATTRIBUTE_NOT_FOUND); + assertThat(e).hasCauseThat().isNull(); } @Test @@ -177,8 +177,8 @@ public void selectField_nonProtoObjectError() { CelRuntimeException e = Assert.assertThrows( CelRuntimeException.class, () -> provider.selectField("hello", "not_a_field")); - assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class); assertThat(e.getErrorCode()).isEqualTo(CelErrorCode.ATTRIBUTE_NOT_FOUND); + assertThat(e).hasCauseThat().isNull(); } @Test diff --git a/runtime/src/test/java/dev/cel/runtime/ProtoMessageRuntimeEqualityTest.java b/runtime/src/test/java/dev/cel/runtime/ProtoMessageRuntimeEqualityTest.java index 16806c856..dc4607e5f 100644 --- a/runtime/src/test/java/dev/cel/runtime/ProtoMessageRuntimeEqualityTest.java +++ b/runtime/src/test/java/dev/cel/runtime/ProtoMessageRuntimeEqualityTest.java @@ -42,7 +42,7 @@ import com.google.rpc.context.AttributeContext.Request; import dev.cel.common.CelDescriptorUtil; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelRuntimeException; import dev.cel.common.internal.AdaptingTypes; import dev.cel.common.internal.BidiConverter; import dev.cel.common.internal.DefaultDescriptorPool; diff --git a/runtime/src/test/java/dev/cel/runtime/ProtoMessageRuntimeHelpersTest.java b/runtime/src/test/java/dev/cel/runtime/ProtoMessageRuntimeHelpersTest.java index f6d701741..45b050fd1 100644 --- a/runtime/src/test/java/dev/cel/runtime/ProtoMessageRuntimeHelpersTest.java +++ b/runtime/src/test/java/dev/cel/runtime/ProtoMessageRuntimeHelpersTest.java @@ -36,7 +36,8 @@ import com.google.protobuf.UInt64Value; import com.google.protobuf.Value; import dev.cel.common.CelOptions; -import dev.cel.common.CelRuntimeException; +import dev.cel.common.exceptions.CelNumericOverflowException; +import dev.cel.common.exceptions.CelRuntimeException; import dev.cel.common.internal.DefaultMessageFactory; import dev.cel.common.internal.DynamicProto; import dev.cel.common.values.CelByteString; @@ -91,7 +92,7 @@ public void int64Divide() throws Exception { assertThat(ProtoMessageRuntimeHelpers.int64Divide(Long.MIN_VALUE, -1, CelOptions.LEGACY)) .isEqualTo(Long.MIN_VALUE); assertThrows( - ArithmeticException.class, + CelNumericOverflowException.class, () -> ProtoMessageRuntimeHelpers.int64Divide(Long.MIN_VALUE, -1, CelOptions.DEFAULT)); } @@ -171,7 +172,7 @@ public void uint64Add_signedLongs() throws Exception { assertThat(ProtoMessageRuntimeHelpers.uint64Add(4, 4, CelOptions.DEFAULT)).isEqualTo(8); assertThat(ProtoMessageRuntimeHelpers.uint64Add(-1, 1, CelOptions.LEGACY)).isEqualTo(0); assertThrows( - ArithmeticException.class, + CelNumericOverflowException.class, () -> ProtoMessageRuntimeHelpers.uint64Add(-1, 1, CelOptions.DEFAULT)); } @@ -185,7 +186,7 @@ public void uint64Add_unsignedLongs() throws Exception { UnsignedLong.MAX_VALUE.minus(UnsignedLong.ONE), UnsignedLong.ONE)) .isEqualTo(UnsignedLong.MAX_VALUE); assertThrows( - ArithmeticException.class, + CelNumericOverflowException.class, () -> ProtoMessageRuntimeHelpers.uint64Add(UnsignedLong.MAX_VALUE, UnsignedLong.ONE)); } @@ -202,7 +203,7 @@ public void uint64Multiply_signedLongs() throws Exception { .build())) .isEqualTo(0); assertThrows( - ArithmeticException.class, + CelNumericOverflowException.class, () -> ProtoMessageRuntimeHelpers.uint64Multiply(Long.MIN_VALUE, 2, CelOptions.DEFAULT)); } @@ -213,7 +214,7 @@ public void uint64Multiply_unsignedLongs() throws Exception { UnsignedLong.valueOf(32), UnsignedLong.valueOf(2))) .isEqualTo(UnsignedLong.valueOf(64)); assertThrows( - ArithmeticException.class, + CelNumericOverflowException.class, () -> ProtoMessageRuntimeHelpers.uint64Multiply( UnsignedLong.MAX_VALUE, UnsignedLong.valueOf(2))); @@ -295,13 +296,13 @@ public void uint64Subtract_signedLongs() throws Exception { assertThat(ProtoMessageRuntimeHelpers.uint64Subtract(-1, 2, CelOptions.DEFAULT)).isEqualTo(-3); assertThat(ProtoMessageRuntimeHelpers.uint64Subtract(0, 1, CelOptions.LEGACY)).isEqualTo(-1); assertThrows( - ArithmeticException.class, + CelNumericOverflowException.class, () -> ProtoMessageRuntimeHelpers.uint64Subtract(0, 1, CelOptions.DEFAULT)); assertThrows( - ArithmeticException.class, + CelNumericOverflowException.class, () -> ProtoMessageRuntimeHelpers.uint64Subtract(-3, -1, CelOptions.DEFAULT)); assertThrows( - ArithmeticException.class, + CelNumericOverflowException.class, () -> ProtoMessageRuntimeHelpers.uint64Subtract(55, -40, CelOptions.DEFAULT)); } @@ -314,7 +315,7 @@ public void uint64Subtract_unsignedLongs() throws Exception { UnsignedLong.valueOf(3), UnsignedLong.valueOf(2))) .isEqualTo(UnsignedLong.ONE); assertThrows( - ArithmeticException.class, + CelNumericOverflowException.class, () -> ProtoMessageRuntimeHelpers.uint64Subtract(UnsignedLong.ONE, UnsignedLong.valueOf(2))); } diff --git a/runtime/src/test/java/dev/cel/runtime/planner/BUILD.bazel b/runtime/src/test/java/dev/cel/runtime/planner/BUILD.bazel index 9e3a79ed9..7ddbf07dc 100644 --- a/runtime/src/test/java/dev/cel/runtime/planner/BUILD.bazel +++ b/runtime/src/test/java/dev/cel/runtime/planner/BUILD.bazel @@ -23,6 +23,7 @@ java_library( "//common:operator", "//common:options", "//common/ast", + "//common/exceptions:divide_by_zero", "//common/internal:cel_descriptor_pools", "//common/internal:default_message_factory", "//common/internal:dynamic_proto", diff --git a/runtime/src/test/java/dev/cel/runtime/planner/ProgramPlannerTest.java b/runtime/src/test/java/dev/cel/runtime/planner/ProgramPlannerTest.java index 205e2ef8b..29220d4a4 100644 --- a/runtime/src/test/java/dev/cel/runtime/planner/ProgramPlannerTest.java +++ b/runtime/src/test/java/dev/cel/runtime/planner/ProgramPlannerTest.java @@ -38,6 +38,7 @@ import dev.cel.common.CelSource; import dev.cel.common.Operator; import dev.cel.common.ast.CelExpr; +import dev.cel.common.exceptions.CelDivideByZeroException; import dev.cel.common.internal.CelDescriptorPool; import dev.cel.common.internal.DefaultDescriptorPool; import dev.cel.common.internal.DefaultMessageFactory; @@ -516,7 +517,7 @@ public void plan_call_logicalOr_throws(String expression) throws Exception { CelEvaluationException e = assertThrows(CelEvaluationException.class, program::eval); // TODO: Tag metadata (source loc) assertThat(e).hasMessageThat().isEqualTo("evaluation error: / by zero"); - assertThat(e).hasCauseThat().isInstanceOf(ArithmeticException.class); + assertThat(e).hasCauseThat().isInstanceOf(CelDivideByZeroException.class); assertThat(e.getErrorCode()).isEqualTo(CelErrorCode.DIVIDE_BY_ZERO); } @@ -548,7 +549,7 @@ public void plan_call_logicalAnd_throws(String expression) throws Exception { CelEvaluationException e = assertThrows(CelEvaluationException.class, program::eval); // TODO: Tag metadata (source loc) assertThat(e).hasMessageThat().isEqualTo("evaluation error: / by zero"); - assertThat(e).hasCauseThat().isInstanceOf(ArithmeticException.class); + assertThat(e).hasCauseThat().isInstanceOf(CelDivideByZeroException.class); assertThat(e.getErrorCode()).isEqualTo(CelErrorCode.DIVIDE_BY_ZERO); } @@ -577,7 +578,7 @@ public void plan_call_conditional_throws(String expression) throws Exception { CelEvaluationException e = assertThrows(CelEvaluationException.class, program::eval); assertThat(e).hasMessageThat().isEqualTo("evaluation error: / by zero"); - assertThat(e).hasCauseThat().isInstanceOf(ArithmeticException.class); + assertThat(e).hasCauseThat().isInstanceOf(CelDivideByZeroException.class); assertThat(e.getErrorCode()).isEqualTo(CelErrorCode.DIVIDE_BY_ZERO); }