diff --git a/litellm/litellm_core_utils/exception_mapping_utils.py b/litellm/litellm_core_utils/exception_mapping_utils.py index 6d39f272f3e..94f4dc71d3e 100644 --- a/litellm/litellm_core_utils/exception_mapping_utils.py +++ b/litellm/litellm_core_utils/exception_mapping_utils.py @@ -1281,6 +1281,27 @@ def _map_vertex_exception( ) -> None: status_code: Final[object] = getattr(original_exception, "status_code", None) body_code: Final[int | None] = _get_body_error_code(error_str) + if ( + exception_type == "TransportError" + or "TransportError" in type(original_exception).__name__ + or "google.auth.exceptions.TransportError" in str(type(original_exception)) + ): + raise APIConnectionError( + message=f"{custom_llm_provider.capitalize()}Exception - Authentication TransportError: {error_str}", + llm_provider=custom_llm_provider, + model=model, + litellm_debug_info=extra_information, + ) + if ( + exception_type in ("RefreshError", "GoogleAuthError", "DefaultCredentialsError") + or "google.auth.exceptions" in str(type(original_exception)) + ): + raise AuthenticationError( + message=f"{custom_llm_provider.capitalize()}Exception - Authentication Error: {error_str}", + llm_provider=custom_llm_provider, + model=model, + litellm_debug_info=extra_information, + ) if "Vertex AI API has not been used in project" in error_str or "Unable to find your project" in error_str: raise BadRequestError( message=f"litellm.BadRequestError: {custom_llm_provider}Exception - {error_str}", diff --git a/tests/unit/litellm_core_utils/test_exception_mapping_utils.py b/tests/unit/litellm_core_utils/test_exception_mapping_utils.py index 32a99a37870..1ce3614798a 100644 --- a/tests/unit/litellm_core_utils/test_exception_mapping_utils.py +++ b/tests/unit/litellm_core_utils/test_exception_mapping_utils.py @@ -792,6 +792,37 @@ def test_vertex_wrapped_500_with_body_code_403_maps_to_bad_request() -> None: assert excinfo.value.status_code == 403 +def test_vertex_auth_transport_error_maps_to_api_connection_error() -> None: + import google.auth.exceptions + original_exception = google.auth.exceptions.TransportError("Socket timeout") + + with pytest.raises(litellm.APIConnectionError) as excinfo: + exception_type( + model="gemini/gemini-2.5-flash", + original_exception=original_exception, + custom_llm_provider="vertex_ai", + ) + + assert isinstance(excinfo.value, litellm.APIConnectionError) + assert "Authentication TransportError" in str(excinfo.value) + assert "https://github.com/BerriAI/litellm/issues/new" not in str(excinfo.value) + + +def test_vertex_auth_refresh_error_maps_to_authentication_error() -> None: + import google.auth.exceptions + original_exception = google.auth.exceptions.RefreshError("Token has been expired or revoked") + + with pytest.raises(litellm.AuthenticationError) as excinfo: + exception_type( + model="gemini/gemini-2.5-flash", + original_exception=original_exception, + custom_llm_provider="vertex_ai", + ) + + assert isinstance(excinfo.value, litellm.AuthenticationError) + assert excinfo.value.status_code == 401 + + class TestGetBodyErrorCode: """Unit tests for _get_body_error_code helper."""