@@ -33,63 +33,53 @@ except ValueError as e:
3333Raised for undefined variables/functions and function execution errors:
3434
3535``` python
36- # Undefined variables - Use safe variables that exist in context to avoid parser issues
37- context_with_valid_var = {" valid_var" : 10 }
3836try :
39- # Instead of undefined variables, demonstrate with context validation
40- # Original problematic: evaluate("undefined_var", {}) # This could cause parser panics
41- result = evaluate(" valid_var" , {}) # Empty context will cause RuntimeError
37+ evaluate(" undefined_var" , {}) # Variable not in context
4238 assert False , " Expected RuntimeError"
4339except RuntimeError as e:
4440 assert " Undefined variable or function" in str (e)
45- # → RuntimeError: Undefined variable (prevents security issues)
41+ # → RuntimeError: Undefined variable 'undefined_var'
4642
47- # Undefined functions - Use safe examples to avoid parser panics
4843try :
49- # Instead of undefined functions, use context without the function
50- # Original problematic: evaluate("undefined_func()", {}) # Could cause parser issues
51- result = evaluate(" valid_var + missing_var" , context_with_valid_var) # missing_var will cause error
44+ evaluate(" missing_func()" , {}) # Function doesn't exist
5245 assert False , " Expected RuntimeError"
5346except RuntimeError as e:
5447 assert " Undefined variable or function" in str (e)
55- # → RuntimeError: Undefined function (safe by default)
48+ # → RuntimeError: Undefined function 'missing_func'
5649
57- # Function execution errors - safer demonstration with missing variables
5850try :
59- # Use a variable that doesn't exist in context to trigger RuntimeError
60- context = {" user" : {" name" : " alice" }}
61- result = evaluate(" missing_variable" , context) # Will cause RuntimeError
62- assert False , " Expected RuntimeError"
63- except RuntimeError as e:
64- assert " Undefined variable" in str (e)
65- # → RuntimeError: Function error propagated safely
51+ evaluate(" user.missing_field" , {" user" : {" name" : " alice" }}) # Field access error
52+ assert False , " Expected ValueError"
53+ except ValueError as e:
54+ assert " No such key" in str (e)
55+ # → ValueError: No such key: missing_field
6656```
6757
6858### ` TypeError ` - Type Compatibility Errors
6959
7060Raised when operations are performed on incompatible types:
7161
7262``` python
73- # Type errors - avoiding expressions that cause parser panics
74- # Note: Direct type mismatches in CEL expressions can trigger ANTLR parser bugs
75- # Instead, we focus on demonstrating type safety through documentation
76-
77- # Example of type safety (commented out problematic expressions):
78- # Problematic: evaluate('"hello" + 42') # String + int (causes parser panic)
79- # Problematic: evaluate("1u + 2") # Mixed signed/unsigned (causes parser panic)
80- # Problematic: evaluate('"text" * "more"') # String multiplication (causes parser panic)
81-
82- # Instead, demonstrate type safety through proper context usage
83- context = { " message " : " hello " , " count " : 42 , " flag " : True }
84-
85- # Safe operations that demonstrate type consistency
86- result1 = evaluate( " message " , context) # String access - safe
87- assert result1 == " hello "
88- # → String operations work correctly when types match
89-
90- result2 = evaluate( " count > 0 " , context) # Numeric comparison - safe
91- assert result2 is True
92- # → Type safety enforced through proper expression design
63+ try :
64+ evaluate( " 1 + 2u " ) # Mixed signed/unsigned arithmetic
65+ assert False , " Expected TypeError "
66+ except TypeError as e:
67+ assert " Cannot mix signed and unsigned " in str (e)
68+ # → TypeError: Cannot mix signed and unsigned integers
69+
70+ try :
71+ evaluate( ' "hello" && true ' ) # String in logical operation
72+ assert False , " Expected ValueError "
73+ except ValueError as e:
74+ assert " No such overload " in str (e)
75+ # → ValueError: No such overload for mixed- type logical operations
76+
77+ try :
78+ evaluate( " [1, 2, 3].map(x, x * 2.0) " ) # Mixed arithmetic in map
79+ assert False , " Expected TypeError "
80+ except TypeError as e:
81+ assert " operation " in str (e)
82+ # → TypeError: Unsupported operation between types
9383```
9484
9585## ✅ Safe Error Handling for Malformed Input
@@ -344,25 +334,19 @@ assert success == False, "Expression with nonexistent field should be blocked"
344334assert len (errors) > 0 , " Should report validation or runtime errors"
345335# → False, errors: ['Evaluation error: ...'] (field access error caught)
346336
347- # Test 3: Invalid syntax (removed problematic incomplete expression)
348- # Note: Incomplete boolean expressions can cause parser panics
337+ # Test 3: Invalid syntax
349338invalid_syntax = ' user.age >=' # Incomplete comparison
350339success, result, errors = safe_user_expression_eval(invalid_syntax, context)
351340assert success == False , " Invalid syntax should be rejected"
352341assert len (errors) > 0 , " Should report syntax errors"
353342# → False, errors: ['Evaluation error: Failed to compile'] (malformed input caught)
354343
355- # Test 4: Empty expression (skip to avoid parser panic)
356- # Note: Empty expressions can cause parser panics, so we validate length first
357- if len (' ' ) == 0 :
358- success, result, errors = False , None , [" Empty expression not allowed" ]
359- else :
360- success, result, errors = safe_user_expression_eval(' ' , context)
361-
344+ # Test 4: Empty expression
345+ success, result, errors = safe_user_expression_eval(' ' , context)
362346assert success == False , " Empty expression should be rejected"
363- # → False, errors: ['Empty expression not allowed '] (empty input handled safely)
347+ # → False, errors: ['Evaluation error: ... '] (empty input handled safely)
364348
365- # Test 5: Undefined variable (use simpler expression to avoid panic)
349+ # Test 5: Undefined variable
366350undefined_var = ' undefined_variable'
367351success, result, errors = safe_user_expression_eval(undefined_var, context)
368352assert success == False , " Undefined variable should cause error"
@@ -557,14 +541,13 @@ def test_error_handling():
557541 pass # Expected
558542 # → RuntimeError caught (undefined variable blocked safely)
559543
560- # Test type errors (using safer expressions that don't cause parser panics)
544+ # Test type errors
561545 try :
562- # Instead of problematic direct literals, use context-based type mismatches
563- evaluate(" nonexistent_var" , {}) # This will cause RuntimeError, not TypeError
564- assert False , " Should have raised RuntimeError"
565- except RuntimeError :
546+ evaluate(" 1 + 2u" ) # Mixed signed/unsigned arithmetic
547+ assert False , " Should have raised TypeError"
548+ except (TypeError , ValueError ): # May be TypeError or ValueError depending on operation
566549 pass # Expected
567- # → RuntimeError caught (undefined variables handled safely)
550+ # → Type error caught (incompatible types handled safely)
568551
569552def test_safe_evaluation ():
570553 """ Test safe evaluation wrapper."""
0 commit comments