"""Test cortex_search exceptions module.""" import pytest from snowflake.connector.errors import ( BadRequest, ForbiddenError, InternalServerError, RequestTimeoutError, TokenExpiredError, TooManyRequests, ) from snowflake.connector.network import ReauthenticationRequest from snowflake.core import exceptions as core_exceptions from payment.connectors.cortex_search.exceptions import ( CortexSearchAuthError, CortexSearchBadRequestError, CortexSearchConfigError, CortexSearchError, CortexSearchNotFoundError, CortexSearchRateLimitError, CortexSearchServiceError, CortexSearchTimeoutError, CortexSearchTokenExpiredError, map_snowflake_error, RETRYABLE_ERRORS, ) def _make_exc(cls, message='test error'): exc = Exception.__new__(cls) # snowflake.connector.errors.Error.__str__ reads self.msg exc.msg = message # snowflake.core.exceptions.APIError and __str__ reads these attributes exc.status = 500 exc.reason = message exc.body = None exc.headers = None exc.request_id = None exc.root = None Exception.__init__(exc, message) return exc class TestExceptionHierarchy: def test_config_error_is_cortex_error(self): assert issubclass(CortexSearchConfigError, CortexSearchError) def test_auth_error_is_cortex_error(self): assert issubclass(CortexSearchAuthError, CortexSearchError) def test_token_expired_is_auth_error(self): assert issubclass(CortexSearchTokenExpiredError, CortexSearchAuthError) def test_bad_request_is_cortex_error(self): assert issubclass(CortexSearchBadRequestError, CortexSearchError) def test_rate_limit_is_cortex_error(self): assert issubclass(CortexSearchRateLimitError, CortexSearchError) def test_service_error_is_cortex_error(self): assert issubclass(CortexSearchServiceError, CortexSearchError) def test_timeout_is_cortex_error(self): assert issubclass(CortexSearchTimeoutError, CortexSearchError) def test_not_found_is_cortex_error(self): assert issubclass(CortexSearchNotFoundError, CortexSearchError) class TestRetryableErrors: def test_rate_limit_is_retryable(self): assert CortexSearchRateLimitError in RETRYABLE_ERRORS def test_service_error_is_retryable(self): assert CortexSearchServiceError in RETRYABLE_ERRORS def test_timeout_is_retryable(self): assert CortexSearchTimeoutError in RETRYABLE_ERRORS def test_token_expired_is_retryable(self): assert CortexSearchTokenExpiredError in RETRYABLE_ERRORS def test_auth_error_is_not_retryable(self): assert CortexSearchAuthError not in RETRYABLE_ERRORS def test_config_error_is_not_retryable(self): assert CortexSearchConfigError not in RETRYABLE_ERRORS class TestMapSnowflakeError: @pytest.mark.parametrize( 'snowflake_cls,expected_cls', [ (BadRequest, CortexSearchBadRequestError), (ForbiddenError, CortexSearchAuthError), (TokenExpiredError, CortexSearchTokenExpiredError), (TooManyRequests, CortexSearchRateLimitError), (InternalServerError, CortexSearchServiceError), (RequestTimeoutError, CortexSearchTimeoutError), (core_exceptions.UnauthorizedError, CortexSearchTokenExpiredError), (core_exceptions.ForbiddenError, CortexSearchAuthError), (core_exceptions.NotFoundError, CortexSearchNotFoundError), (core_exceptions.ServerError, CortexSearchServiceError), (core_exceptions.ConflictError, CortexSearchError), (core_exceptions.RetryTimeoutError, CortexSearchTimeoutError), (core_exceptions.InvalidArgumentsError, CortexSearchBadRequestError), (ReauthenticationRequest, CortexSearchTokenExpiredError), ], ) def test_maps_known_errors(self, snowflake_cls, expected_cls): exc = _make_exc(snowflake_cls, 'some error') result = map_snowflake_error(exc) # Exact-type check (not isinstance): CortexSearchTokenExpiredError # is a subclass of CortexSearchAuthError, and we want to catch a # regression that maps Forbidden* to the token-expired subclass. assert type(result) is expected_cls def test_preserves_message(self): exc = _make_exc(BadRequest, 'bad input') result = map_snowflake_error(exc) assert str(result) == 'bad input' def test_unknown_error_returns_base(self): exc = Exception('totally unknown') result = map_snowflake_error(exc) assert type(result) is CortexSearchError