| import pytest |
| from unittest.mock import MagicMock |
| from ankigen.exceptions import ( |
| AnkigenError, |
| ValidationError, |
| SecurityError, |
| APIError, |
| OpenAIAPIError, |
| Context7APIError, |
| ExportError, |
| CardGenerationError, |
| ConfigurationError, |
| handle_exception, |
| ) |
|
|
|
|
| def test_exception_hierarchy(): |
| """Test that all exceptions inherit correctly from AnkigenError.""" |
| assert issubclass(ValidationError, AnkigenError) |
| assert issubclass(SecurityError, AnkigenError) |
| assert issubclass(APIError, AnkigenError) |
| assert issubclass(OpenAIAPIError, APIError) |
| assert issubclass(OpenAIAPIError, AnkigenError) |
| assert issubclass(Context7APIError, APIError) |
| assert issubclass(Context7APIError, AnkigenError) |
| assert issubclass(ExportError, AnkigenError) |
| assert issubclass(CardGenerationError, AnkigenError) |
| assert issubclass(ConfigurationError, AnkigenError) |
|
|
|
|
| def test_exception_catching(): |
| """Test that exceptions can be caught by their parent classes.""" |
| with pytest.raises(AnkigenError): |
| raise ValidationError("Validation failed") |
|
|
| with pytest.raises(APIError): |
| raise OpenAIAPIError("OpenAI API error") |
|
|
| with pytest.raises(AnkigenError): |
| raise OpenAIAPIError("OpenAI API error") |
|
|
|
|
| def test_handle_exception_logging(): |
| """Test that handle_exception logs the error.""" |
| mock_logger = MagicMock() |
| exc = ValueError("Test error") |
| message = "An error occurred" |
|
|
| try: |
| handle_exception(exc, mock_logger, message, reraise=False) |
| except Exception: |
| pytest.fail("handle_exception raised an error when reraise=False") |
|
|
| mock_logger.error.assert_called_once_with(f"{message}: {exc}", exc_info=True) |
|
|
|
|
| def test_handle_exception_reraise_true(): |
| """Test that handle_exception re-raises the original exception when reraise=True.""" |
| mock_logger = MagicMock() |
|
|
| try: |
| raise ValueError("Test error") |
| except ValueError as exc: |
| with pytest.raises(ValueError) as excinfo: |
| handle_exception(exc, mock_logger, "Error", reraise=True) |
| assert str(excinfo.value) == "Test error" |
|
|
|
|
| def test_handle_exception_reraise_as(): |
| """Test that handle_exception wraps the exception in reraise_as type.""" |
| mock_logger = MagicMock() |
| exc = ValueError("Original error") |
| message = "Wrapped error" |
|
|
| with pytest.raises(AnkigenError) as excinfo: |
| handle_exception( |
| exc, mock_logger, message, reraise=True, reraise_as=AnkigenError |
| ) |
|
|
| assert isinstance(excinfo.value, AnkigenError) |
| assert str(excinfo.value) == f"{message}: {exc}" |
| assert excinfo.value.__cause__ is exc |
|
|