Documentation Index Fetch the complete documentation index at: https://mintlify.com/pydantic/monty/llms.txt
Use this file to discover all available pages before exploring further.
Monty provides comprehensive error handling with detailed tracebacks, exception type preservation, and multiple error display formats.
Error Types
Monty has three main error types, all subclasses of MontyError:
MontySyntaxError
Raised when code has syntax errors during parsing:
import pydantic_monty
try :
m = pydantic_monty.Monty( 'def' ) # Invalid syntax
except pydantic_monty.MontySyntaxError as e:
print ( str (e)) # "Expected an identifier at byte range 3..3"
inner = e.exception()
print ( type (inner)) # <class 'SyntaxError'>
MontyRuntimeError
Raised when code encounters a runtime error during execution:
try :
m = pydantic_monty.Monty( '1 / 0' )
m.run()
except pydantic_monty.MontyRuntimeError as e:
inner = e.exception()
print ( type (inner)) # <class 'ZeroDivisionError'>
MontyTypingError
Raised when type checking detects type errors:
try :
m = pydantic_monty.Monty( '"hello" + 1' , type_check = True )
except pydantic_monty.MontyTypingError as e:
print (e.display( 'concise' ))
All Monty errors inherit from MontyError, so you can catch all Monty-specific errors with a single except clause.
Catching All Monty Errors
import pydantic_monty
try :
m = pydantic_monty.Monty(code, type_check = True )
result = m.run()
except pydantic_monty.MontyError as e:
# Handles all Monty error types
print ( f "Error: { e } " )
Getting the Inner Exception
For MontySyntaxError and MontyRuntimeError, you can access the underlying Python exception:
try :
m = pydantic_monty.Monty( 'undefined_variable' )
m.run()
except pydantic_monty.MontyRuntimeError as e:
inner = e.exception()
print ( type (inner)) # <class 'NameError'>
print ( str (inner)) # "name 'undefined_variable' is not defined"
print ( isinstance (inner, NameError )) # True
Common Runtime Exceptions
Monty preserves standard Python exception types:
ZeroDivisionError
ValueError
TypeError
IndexError
KeyError
NameError
AssertionError
m = pydantic_monty.Monty( '1 / 0' )
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
assert isinstance (e.exception(), ZeroDivisionError )
m = pydantic_monty.Monty( "raise ValueError('bad value')" )
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
inner = e.exception()
assert isinstance (inner, ValueError )
assert str (inner) == 'bad value'
m = pydantic_monty.Monty( "'string' + 1" )
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
assert isinstance (e.exception(), TypeError )
m = pydantic_monty.Monty( '[1, 2, 3][10]' )
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
assert isinstance (e.exception(), IndexError )
m = pydantic_monty.Monty( "{'a': 1}['b']" )
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
assert isinstance (e.exception(), KeyError )
m = pydantic_monty.Monty( 'undefined_variable' )
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
assert isinstance (e.exception(), NameError )
m = pydantic_monty.Monty( "assert False, 'failed'" )
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
inner = e.exception()
assert isinstance (inner, AssertionError )
assert str (inner) == 'failed'
Tracebacks
Monty provides full traceback information for runtime errors:
code = """
def inner():
raise ValueError('error')
def outer():
inner()
outer()
"""
m = pydantic_monty.Monty(code)
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
print (e.display())
Output:
Traceback (most recent call last):
File "main.py", line 7, in <module>
outer()
~~~~~~~
File "main.py", line 5, in outer
inner()
~~~~~~~
File "main.py", line 2, in inner
raise ValueError('error')
ValueError: error
Accessing Traceback Frames
You can access individual traceback frames programmatically:
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
frames = e.traceback()
for frame in frames:
print ( f " { frame.filename } : { frame.line } in { frame.function_name } " )
print ( f " { frame.source_line } " )
Frame Properties
Each frame has these properties:
frame.filename # 'main.py'
frame.line # Line number (1-indexed)
frame.column # Column number (1-indexed)
frame.end_line # End line number
frame.end_column # End column number
frame.function_name # Function name or '<module>'
frame.source_line # The actual source code line
You can also get frame data as a dict:
frame_dict = frame.dict()
# {
# 'filename': 'main.py',
# 'line': 5,
# 'column': 1,
# 'end_line': 5,
# 'end_column': 6,
# 'function_name': '<module>',
# 'source_line': 'foo()'
# }
Control how errors are displayed:
Full Traceback (Default)
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
print (e.display()) # Full traceback with frames
# or
print (e) # Same as display()
Type and Message
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
print (e.display( 'type-msg' )) # "ValueError: bad value"
Message Only
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
print (e.display( 'msg' )) # "bad value"
str(error) returns the same as error.display('type-msg') for easy printing.
JavaScript Error Handling
import { Monty , MontySyntaxError , MontyRuntimeError , MontyTypingError } from '@pydantic/monty'
try {
const m = new Monty ( '1 / 0' )
m . run ()
} catch ( error ) {
if ( error instanceof MontySyntaxError ) {
console . log ( 'Syntax error:' , error . message )
} else if ( error instanceof MontyRuntimeError ) {
console . log ( 'Runtime error:' , error . message )
console . log ( 'Traceback:' , error . traceback ())
} else if ( error instanceof MontyTypingError ) {
console . log ( 'Type error:' , error . displayDiagnostics ())
}
}
Exception Handling Within Monty Code
Monty code can catch and handle exceptions using try/except:
code = """
try:
1 / 0
except ZeroDivisionError as e:
result = 'caught'
result
"""
m = pydantic_monty.Monty(code)
print (m.run()) # 'caught'
Exception Hierarchies
Monty respects Python exception hierarchies:
code = """
try:
raise ZeroDivisionError('math error')
except ArithmeticError: # Parent class catches child
caught = 'parent'
except ZeroDivisionError:
caught = 'child'
caught
"""
m = pydantic_monty.Monty(code)
print (m.run()) # 'parent'
Supported exception hierarchies:
ArithmeticError → ZeroDivisionError, OverflowError
LookupError → KeyError, IndexError
RuntimeError → NotImplementedError, RecursionError
Exceptions from External Functions
Exceptions raised by external functions propagate to Monty code:
def fail ():
raise ValueError ( 'external error' )
code = """
try:
fail()
except ValueError:
caught = True
caught
"""
m = pydantic_monty.Monty(code)
result = m.run( external_functions = { 'fail' : fail})
print (result) # True
Exception types are preserved across the boundary. A ValueError raised by an external function is a ValueError in Monty code.
Uncaught External Exceptions
If Monty code doesn’t catch an exception from an external function, it propagates to the host:
def fail ():
raise RuntimeError ( 'uncaught' )
m = pydantic_monty.Monty( 'fail()' )
try :
m.run( external_functions = { 'fail' : fail})
except pydantic_monty.MontyRuntimeError as e:
inner = e.exception()
print ( type (inner)) # <class 'RuntimeError'>
print ( str (inner)) # 'uncaught'
Exceptions During Iterative Execution
You can resume execution with an exception:
code = """
try:
result = external_func()
except ValueError:
caught = True
caught
"""
m = pydantic_monty.Monty(code)
progress = m.start()
# Resume with an exception instead of a return value
result = progress.resume( exception = ValueError ( 'test error' ))
print (result.output) # True
Uncaught Exception in Resume
code = 'external_func()'
m = pydantic_monty.Monty(code)
progress = m.start()
try :
# Exception not caught by Monty code
progress.resume( exception = ValueError ( 'uncaught' ))
except pydantic_monty.MontyRuntimeError as e:
inner = e.exception()
print ( type (inner)) # <class 'ValueError'>
Best Practices
Catch specific errors first
Handle specific errors before catching general MontyError: try :
m.run()
except pydantic_monty.MontySyntaxError:
# Handle syntax errors
pass
except pydantic_monty.MontyRuntimeError:
# Handle runtime errors
pass
except pydantic_monty.MontyError:
# Catch-all for other Monty errors
pass
Log tracebacks for debugging
Always log the full traceback for runtime errors: try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
logger.error( f "Runtime error: { e.display() } " )
Provide helpful error messages
When raising exceptions from external functions, provide clear messages: def fetch_data ( url : str ):
if not url.startswith( 'https://' ):
raise ValueError ( f "URL must use HTTPS: { url } " )
# ...
Handle errors in Monty code when possible
Encourage your agent to use try/except in generated code: code = """
try:
result = risky_operation()
except ValueError as e:
result = default_value
result
"""
Always catch MontyError or its subclasses. Don’t let Monty exceptions crash your application.
Error Messages for LLMs
When providing error feedback to LLMs, use concise formats:
try :
m = pydantic_monty.Monty(llm_generated_code, type_check = True )
result = m.run()
except pydantic_monty.MontyTypingError as e:
# Send concise type error back to LLM
feedback = e.display( 'concise' )
print ( f "Type error: { feedback } " )
except pydantic_monty.MontyRuntimeError as e:
# Send type and message back to LLM
feedback = e.display( 'type-msg' )
print ( f "Runtime error: { feedback } " )
Testing Error Handling
Test that your code handles errors correctly:
import pytest
import pydantic_monty
def test_handles_zero_division ():
m = pydantic_monty.Monty( '1 / 0' )
with pytest.raises(pydantic_monty.MontyRuntimeError) as exc_info:
m.run()
inner = exc_info.value.exception()
assert isinstance (inner, ZeroDivisionError )
def test_handles_missing_function ():
m = pydantic_monty.Monty( 'missing_func()' )
with pytest.raises(pydantic_monty.MontyRuntimeError) as exc_info:
m.run()
inner = exc_info.value.exception()
assert isinstance (inner, NameError )
assert "'missing_func'" in str (inner)
Repr for Debugging
All error types have helpful repr() implementations:
try :
m.run()
except pydantic_monty.MontyRuntimeError as e:
print ( repr (e))
# MontyRuntimeError(ValueError: test message)
Next Steps
Type Checking Catch errors before runtime with type checking
External Functions Learn how external function errors propagate