diff --git a/runtime/src/main/java/dev/cel/runtime/ResolvedOverload.java b/runtime/src/main/java/dev/cel/runtime/ResolvedOverload.java index a46a92fae..5d632e695 100644 --- a/runtime/src/main/java/dev/cel/runtime/ResolvedOverload.java +++ b/runtime/src/main/java/dev/cel/runtime/ResolvedOverload.java @@ -72,9 +72,10 @@ default boolean canHandle(Object[] arguments) { } if (arg instanceof Exception || arg instanceof CelUnknownSet) { + // Only non-strict functions can accept errors/unknowns as arguments to a function if (!isStrict()) { - // Only non-strict functions can accept errors/unknowns as arguments to a function - return true; + // Skip assignability check below, but continue to validate remaining args + continue; } } diff --git a/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java b/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java index 0fdc4f65d..40e2075aa 100644 --- a/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java +++ b/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java @@ -65,4 +65,35 @@ public void canHandle_nonMatchingTypes_returnsFalse() { public void canHandle_nonMatchingArgCount_returnsFalse() { assertThat(getIncrementIntOverload().canHandle(new Object[] {1L, 2L})).isFalse(); } + + @Test + public void canHandle_nonStrictOverload_returnsTrue() { + CelResolvedOverload nonStrictOverload = + CelResolvedOverload.of( + "non_strict", + (args) -> { + return false; + }, + /* isStrict= */ false, + Long.class, + Long.class); + assertThat( + nonStrictOverload.canHandle( + new Object[] {new RuntimeException(), CelUnknownSet.create()})) + .isTrue(); + } + + @Test + public void canHandle_nonStrictOverload_returnsFalse() { + CelResolvedOverload nonStrictOverload = + CelResolvedOverload.of( + "non_strict", + (args) -> { + return false; + }, + /* isStrict= */ false, + Long.class, + Long.class); + assertThat(nonStrictOverload.canHandle(new Object[] {new RuntimeException(), "Foo"})).isFalse(); + } }