Skip to content

Commit b3612d4

Browse files
l46kokcopybara-github
authored andcommitted
Introduce CEL exception classes that correspond to canonical error codes
PiperOrigin-RevId: 844506576
1 parent 18a12b6 commit b3612d4

11 files changed

+348
-15
lines changed

common/exceptions/BUILD.bazel

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
load("@rules_java//java:defs.bzl", "java_library")
2+
3+
package(
4+
default_applicable_licenses = ["//:license"],
5+
default_visibility = ["//:internal"],
6+
)
7+
8+
java_library(
9+
name = "attribute_not_found",
10+
# used_by_android
11+
exports = ["//common/src/main/java/dev/cel/common/exceptions:attribute_not_found"],
12+
)
13+
14+
java_library(
15+
name = "divide_by_zero",
16+
# used_by_android
17+
exports = ["//common/src/main/java/dev/cel/common/exceptions:divide_by_zero"],
18+
)
19+
20+
java_library(
21+
name = "index_out_of_bounds",
22+
# used_by_android
23+
exports = ["//common/src/main/java/dev/cel/common/exceptions:index_out_of_bounds"],
24+
)
25+
26+
java_library(
27+
name = "bad_format",
28+
# used_by_android
29+
exports = ["//common/src/main/java/dev/cel/common/exceptions:bad_format"],
30+
)
31+
32+
java_library(
33+
name = "numeric_overflow",
34+
# used_by_android
35+
exports = ["//common/src/main/java/dev/cel/common/exceptions:numeric_overflow"],
36+
)
37+
38+
java_library(
39+
name = "invalid_argument",
40+
# used_by_android
41+
exports = ["//common/src/main/java/dev/cel/common/exceptions:invalid_argument"],
42+
)

common/src/main/java/dev/cel/common/BUILD.bazel

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ java_library(
205205
],
206206
deps = [
207207
":cel_source",
208-
"//:auto_value",
209208
"//common/ast:mutable_expr",
210209
"@maven//:com_google_errorprone_error_prone_annotations",
211210
"@maven//:com_google_guava_guava",
@@ -249,7 +248,6 @@ java_library(
249248
":source",
250249
":source_location",
251250
"//:auto_value",
252-
"//common/annotations",
253251
"//common/ast",
254252
"//common/internal",
255253
"@maven//:com_google_errorprone_error_prone_annotations",
@@ -360,8 +358,5 @@ java_library(
360358
srcs = ["Operator.java"],
361359
tags = [
362360
],
363-
deps = [
364-
"//common/ast",
365-
"@maven//:com_google_guava_guava",
366-
],
361+
deps = ["@maven//:com_google_guava_guava"],
367362
)

common/src/main/java/dev/cel/common/CelException.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,6 @@ public CelException(String message, Throwable cause) {
2727
super(message, cause);
2828
}
2929

30-
public CelException(String message, CelErrorCode errorCode) {
31-
super(message);
32-
this.errorCode = errorCode;
33-
}
34-
3530
public CelException(String message, Throwable cause, CelErrorCode errorCode) {
3631
super(message, cause);
3732
this.errorCode = errorCode;

common/src/main/java/dev/cel/common/CelRuntimeException.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,17 @@
2020
* Wrapper for an unchecked runtime exception with a CelErrorCode supplied.
2121
*
2222
* <p>Note: This is not to be confused with the notion of CEL Runtime. Use {@code
23-
* CelEvaluationException} instead to signify an evaluation error.
24-
*
25-
* <p>TODO: Make this class abstract and define specific exception classes that
26-
* corresponds to the CelErrorCode.
23+
* CelEvaluationException} instead to signify an evaluation error. corresponds to the CelErrorCode.
2724
*/
2825
@Internal
2926
public class CelRuntimeException extends RuntimeException {
3027
private final CelErrorCode errorCode;
3128

29+
public CelRuntimeException(String errorMessage, CelErrorCode errorCode) {
30+
super(errorMessage);
31+
this.errorCode = errorCode;
32+
}
33+
3234
public CelRuntimeException(Throwable cause, CelErrorCode errorCode) {
3335
super(cause);
3436
this.errorCode = errorCode;
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
load("@rules_java//java:defs.bzl", "java_library")
2+
3+
package(
4+
default_applicable_licenses = ["//:license"],
5+
default_visibility = [
6+
"//common/exceptions:__pkg__",
7+
"//publish:__pkg__",
8+
],
9+
)
10+
11+
java_library(
12+
name = "attribute_not_found",
13+
srcs = ["CelAttributeNotFoundException.java"],
14+
# used_by_android
15+
tags = [
16+
],
17+
deps = [
18+
"//common:error_codes",
19+
"//common:runtime_exception",
20+
"//common/annotations",
21+
],
22+
)
23+
24+
java_library(
25+
name = "divide_by_zero",
26+
srcs = ["CelDivideByZeroException.java"],
27+
# used_by_android
28+
tags = [
29+
],
30+
deps = [
31+
"//common:error_codes",
32+
"//common:runtime_exception",
33+
"//common/annotations",
34+
],
35+
)
36+
37+
java_library(
38+
name = "index_out_of_bounds",
39+
srcs = ["CelIndexOutOfBoundsException.java"],
40+
# used_by_android
41+
tags = [
42+
],
43+
deps = [
44+
"//common:error_codes",
45+
"//common:runtime_exception",
46+
"//common/annotations",
47+
],
48+
)
49+
50+
java_library(
51+
name = "bad_format",
52+
srcs = ["CelBadFormatException.java"],
53+
# used_by_android
54+
tags = [
55+
],
56+
deps = [
57+
"//common:error_codes",
58+
"//common:runtime_exception",
59+
"//common/annotations",
60+
],
61+
)
62+
63+
java_library(
64+
name = "numeric_overflow",
65+
srcs = ["CelNumericOverflowException.java"],
66+
# used_by_android
67+
tags = [
68+
],
69+
deps = [
70+
"//common:error_codes",
71+
"//common:runtime_exception",
72+
"//common/annotations",
73+
],
74+
)
75+
76+
java_library(
77+
name = "invalid_argument",
78+
srcs = ["CelInvalidArgumentException.java"],
79+
# used_by_android
80+
tags = [
81+
],
82+
deps = [
83+
"//common:error_codes",
84+
"//common:runtime_exception",
85+
"//common/annotations",
86+
],
87+
)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package dev.cel.common.exceptions;
16+
17+
import dev.cel.common.CelErrorCode;
18+
import dev.cel.common.CelRuntimeException;
19+
import dev.cel.common.annotations.Internal;
20+
import java.util.Arrays;
21+
import java.util.Collection;
22+
23+
/** Indicates an attempt to access a map or object using an invalid attribute or key. */
24+
@Internal
25+
public final class CelAttributeNotFoundException extends CelRuntimeException {
26+
27+
public static CelAttributeNotFoundException of(String message) {
28+
return new CelAttributeNotFoundException(message);
29+
}
30+
31+
public static CelAttributeNotFoundException forMissingMapKey(String key) {
32+
return new CelAttributeNotFoundException(String.format("key '%s' is not present in map.", key));
33+
}
34+
35+
public static CelAttributeNotFoundException forFieldResolution(String... fields) {
36+
return forFieldResolution(Arrays.asList(fields));
37+
}
38+
39+
public static CelAttributeNotFoundException forFieldResolution(Collection<String> fields) {
40+
return new CelAttributeNotFoundException(formatErrorMessage(fields));
41+
}
42+
43+
private static String formatErrorMessage(Collection<String> fields) {
44+
String maybePlural = "";
45+
if (fields.size() > 1) {
46+
maybePlural = "s";
47+
}
48+
49+
return String.format(
50+
"Error resolving field%s '%s'. Field selections must be performed on messages or maps.",
51+
maybePlural, String.join(", ", fields));
52+
}
53+
54+
private CelAttributeNotFoundException(String message) {
55+
super(message, CelErrorCode.ATTRIBUTE_NOT_FOUND);
56+
}
57+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package dev.cel.common.exceptions;
16+
17+
import dev.cel.common.CelErrorCode;
18+
import dev.cel.common.CelRuntimeException;
19+
import dev.cel.common.annotations.Internal;
20+
21+
/** Indicates that a data conversion failed due to a mismatch in the format specification. */
22+
@Internal
23+
public final class CelBadFormatException extends CelRuntimeException {
24+
25+
public CelBadFormatException(Throwable cause) {
26+
super(cause, CelErrorCode.BAD_FORMAT);
27+
}
28+
29+
public CelBadFormatException(String errorMessage) {
30+
super(errorMessage, CelErrorCode.BAD_FORMAT);
31+
}
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package dev.cel.common.exceptions;
16+
17+
import dev.cel.common.CelErrorCode;
18+
import dev.cel.common.CelRuntimeException;
19+
import dev.cel.common.annotations.Internal;
20+
21+
/** Indicates that a division by zero occurred. */
22+
@Internal
23+
public final class CelDivideByZeroException extends CelRuntimeException {
24+
25+
public CelDivideByZeroException() {
26+
super("/ by zero", CelErrorCode.DIVIDE_BY_ZERO);
27+
}
28+
29+
public CelDivideByZeroException(Throwable cause) {
30+
super(cause, CelErrorCode.DIVIDE_BY_ZERO);
31+
}
32+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package dev.cel.common.exceptions;
16+
17+
import dev.cel.common.CelErrorCode;
18+
import dev.cel.common.CelRuntimeException;
19+
import dev.cel.common.annotations.Internal;
20+
21+
/** Indicates that a list index access was attempted using an index that is out of bounds. */
22+
@Internal
23+
public final class CelIndexOutOfBoundsException extends CelRuntimeException {
24+
25+
public CelIndexOutOfBoundsException(Object index) {
26+
super("Index out of bounds: " + index, CelErrorCode.INDEX_OUT_OF_BOUNDS);
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package dev.cel.common.exceptions;
16+
17+
import dev.cel.common.CelErrorCode;
18+
import dev.cel.common.CelRuntimeException;
19+
import dev.cel.common.annotations.Internal;
20+
21+
/** Indicates that an invalid argument was supplied to a function. */
22+
@Internal
23+
public final class CelInvalidArgumentException extends CelRuntimeException {
24+
25+
public CelInvalidArgumentException(Throwable cause) {
26+
super(cause, CelErrorCode.INVALID_ARGUMENT);
27+
}
28+
}

0 commit comments

Comments
 (0)