113 lines
3.7 KiB
Python
113 lines
3.7 KiB
Python
"""Test backwards compatibility of exception handling."""
|
|
|
|
import pytest
|
|
from instructor.core.exceptions import (
|
|
InstructorError,
|
|
ResponseParsingError,
|
|
MultimodalError,
|
|
AsyncValidationError,
|
|
)
|
|
|
|
|
|
def test_response_parsing_error_is_value_error():
|
|
"""Test that ResponseParsingError can be caught as ValueError."""
|
|
with pytest.raises(ValueError):
|
|
raise ResponseParsingError("Test error", mode="TOOLS")
|
|
|
|
# Should also be catchable as InstructorError
|
|
with pytest.raises(InstructorError):
|
|
raise ResponseParsingError("Test error", mode="TOOLS")
|
|
|
|
# And as the specific type
|
|
with pytest.raises(ResponseParsingError):
|
|
raise ResponseParsingError("Test error", mode="TOOLS")
|
|
|
|
|
|
def test_multimodal_error_is_value_error():
|
|
"""Test that MultimodalError can be caught as ValueError."""
|
|
with pytest.raises(ValueError):
|
|
raise MultimodalError("Test error", content_type="image")
|
|
|
|
# Should also be catchable as InstructorError
|
|
with pytest.raises(InstructorError):
|
|
raise MultimodalError("Test error", content_type="image")
|
|
|
|
# And as the specific type
|
|
with pytest.raises(MultimodalError):
|
|
raise MultimodalError("Test error", content_type="image")
|
|
|
|
|
|
def test_async_validation_error_is_value_error():
|
|
"""Test that AsyncValidationError can be caught as ValueError."""
|
|
with pytest.raises(ValueError):
|
|
raise AsyncValidationError("Test error")
|
|
|
|
# Should also be catchable as InstructorError
|
|
with pytest.raises(InstructorError):
|
|
raise AsyncValidationError("Test error")
|
|
|
|
|
|
def test_exception_inheritance_chain():
|
|
"""Test that new exceptions have correct inheritance."""
|
|
# ResponseParsingError
|
|
assert issubclass(ResponseParsingError, ValueError)
|
|
assert issubclass(ResponseParsingError, InstructorError)
|
|
assert issubclass(ResponseParsingError, Exception)
|
|
|
|
# MultimodalError
|
|
assert issubclass(MultimodalError, ValueError)
|
|
assert issubclass(MultimodalError, InstructorError)
|
|
assert issubclass(MultimodalError, Exception)
|
|
|
|
# AsyncValidationError
|
|
assert issubclass(AsyncValidationError, ValueError)
|
|
assert issubclass(AsyncValidationError, InstructorError)
|
|
assert issubclass(AsyncValidationError, Exception)
|
|
|
|
|
|
def test_mixed_exception_catching():
|
|
"""Test catching multiple exception types including ValueError."""
|
|
|
|
def raise_parsing_error():
|
|
raise ResponseParsingError("Parsing failed", mode="JSON")
|
|
|
|
def raise_multimodal_error():
|
|
raise MultimodalError(
|
|
"File not found", content_type="image", file_path="/test.jpg"
|
|
)
|
|
|
|
# Catch as ValueError
|
|
with pytest.raises(ValueError):
|
|
raise_parsing_error()
|
|
|
|
with pytest.raises(ValueError):
|
|
raise_multimodal_error()
|
|
|
|
# Catch as InstructorError
|
|
with pytest.raises(InstructorError):
|
|
raise_parsing_error()
|
|
|
|
with pytest.raises(InstructorError):
|
|
raise_multimodal_error()
|
|
|
|
|
|
def test_exception_attributes_preserved():
|
|
"""Test that exception attributes are preserved when caught as ValueError."""
|
|
try:
|
|
raise ResponseParsingError(
|
|
"Parse failed", mode="TOOLS", raw_response={"test": "data"}
|
|
)
|
|
except ValueError as e:
|
|
# Should still be able to access ResponseParsingError attributes
|
|
assert isinstance(e, ResponseParsingError)
|
|
assert e.mode == "TOOLS"
|
|
assert e.raw_response == {"test": "data"}
|
|
|
|
try:
|
|
raise MultimodalError("File error", content_type="pdf", file_path="/test.pdf")
|
|
except ValueError as e:
|
|
# Should still be able to access MultimodalError attributes
|
|
assert isinstance(e, MultimodalError)
|
|
assert e.content_type == "pdf"
|
|
assert e.file_path == "/test.pdf"
|