From 3bbd567a1a0020a5c5962dd9032def0399ee6fca Mon Sep 17 00:00:00 2001 From: Hamza Imran Date: Sun, 1 Nov 2026 17:28:02 +0500 Subject: [PATCH] fix(vertex_ai): map google.auth TransportError to APIConnectionError (#49419) --- .../exception_mapping_utils.py | 21 +++++++++++++ .../test_exception_mapping_utils.py | 31 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/litellm/litellm_core_utils/exception_mapping_utils.py b/litellm/litellm_core_utils/exception_mapping_utils.py index 85c232ad3f4..1e5fc501464 100644 --- a/litellm/litellm_core_utils/exception_mapping_utils.py +++ b/litellm/litellm_core_utils/exception_mapping_utils.py @@ -1272,6 +1272,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 2b1e4a5eed3..ca18c3bdb17 100644 --- a/tests/unit/litellm_core_utils/test_exception_mapping_utils.py +++ b/tests/unit/litellm_core_utils/test_exception_mapping_utils.py @@ -772,6 +772,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."""