fix(vertex passthrough): keep transport failures out of the auth error mapping

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
milan 2026-08-13 22:42:57 +00:00
parent ca6f731d80
commit 8a23564d6e
2 changed files with 45 additions and 3 deletions

View file

@ -14,6 +14,7 @@ from typing import Any, Final, cast
import httpx
from fastapi import APIRouter, Depends, HTTPException, Request, Response, WebSocket
from fastapi.responses import StreamingResponse
from google.auth.exceptions import GoogleAuthError, TransportError
from starlette.websockets import WebSocketState
import litellm
@ -1616,7 +1617,9 @@ async def _prepare_vertex_auth_headers(
custom_llm_provider="vertex_ai_beta",
api_base="",
)
except Exception as e:
except TransportError:
raise
except (GoogleAuthError, ValueError) as e:
raise ProxyException(
message=(
f"Failed to get a Google access token for project={vertex_project} + location={vertex_location}: {e}. "

View file

@ -1,12 +1,11 @@
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from google.auth.exceptions import DefaultCredentialsError
from google.auth.exceptions import DefaultCredentialsError, TransportError
from litellm.proxy.pass_through_endpoints.llm_passthrough_endpoints import (
_base_vertex_proxy_route,
)
from litellm.types.router import DeploymentTypedDict
@pytest.mark.asyncio
@ -396,6 +395,46 @@ async def test_vertex_passthrough_credential_failure_raises_auth_error():
assert "Your default credentials were not found" in exc_info.value.message
@pytest.mark.asyncio
async def test_vertex_passthrough_transport_failure_is_not_reported_as_auth_error():
"""
Reaching Google's token endpoint can fail for reasons the operator cannot fix with
credentials, so those must not be relabelled as authentication errors.
"""
from starlette.datastructures import Headers
from litellm.llms.vertex_ai.vertex_llm_base import VertexBase
from litellm.proxy.pass_through_endpoints.llm_passthrough_endpoints import (
_prepare_vertex_auth_headers,
)
mock_request = MagicMock()
mock_request.headers = Headers({"authorization": "Bearer sk-litellm-key"})
mock_request.state._cached_headers = None
mock_vertex_credentials = MagicMock()
mock_vertex_credentials.vertex_project = "test-project"
mock_vertex_credentials.vertex_location = "us-central1"
mock_vertex_credentials.vertex_credentials = None
with patch.object(
VertexBase,
"_ensure_access_token_async",
new_callable=AsyncMock,
side_effect=TransportError("connection reset by peer"),
):
with pytest.raises(TransportError):
await _prepare_vertex_auth_headers(
request=mock_request,
vertex_credentials=mock_vertex_credentials,
router_credentials=None,
vertex_project="test-project",
vertex_location="us-central1",
base_target_url="https://us-central1-aiplatform.googleapis.com",
get_vertex_pass_through_handler=MagicMock(),
)
@pytest.mark.asyncio
async def test_vertex_passthrough_does_not_forward_litellm_auth_token():
"""