fix(llm_http_handler.py): raise clearer error on anthropic unified route

Fixes https://github.com/BerriAI/litellm/issues/12063
This commit is contained in:
Krrish Dholakia 2025-06-26 15:31:18 -07:00
parent 1de2e4ce28
commit ad31da9685
2 changed files with 95 additions and 53 deletions

View file

@ -1,5 +1,5 @@
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, AsyncIterator, Dict, List, Optional, Tuple
from typing import TYPE_CHECKING, Any, AsyncIterator, Dict, List, Optional, Tuple, Union
import httpx
@ -10,6 +10,7 @@ from litellm.types.router import GenericLiteLLMParams
if TYPE_CHECKING:
from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj
from litellm.llms.base_llm.chat.transformation import BaseLLMException
LiteLLMLoggingObj = _LiteLLMLoggingObj
else:
@ -109,3 +110,10 @@ class BaseAnthropicMessagesConfig(ABC):
litellm_logging_obj: LiteLLMLoggingObj,
) -> AsyncIterator:
raise NotImplementedError("Subclasses must implement this method")
def get_error_class(
self, error_message: str, status_code: int, headers: Union[dict, httpx.Headers]
) -> "BaseLLMException":
return BaseLLMException(
message=error_message, status_code=status_code, headers=headers
)

View file

@ -1333,14 +1333,19 @@ class BaseLLMHTTPHandler:
},
)
response = await async_httpx_client.post(
url=request_url,
headers=headers,
data=signed_json_body or json.dumps(request_body),
stream=stream or False,
logging_obj=logging_obj,
)
response.raise_for_status()
try:
response = await async_httpx_client.post(
url=request_url,
headers=headers,
data=signed_json_body or json.dumps(request_body),
stream=stream or False,
logging_obj=logging_obj,
)
response.raise_for_status()
except Exception as e:
raise self._handle_error(
e=e, provider_config=anthropic_messages_provider_config
)
# used for logging + cost tracking
logging_obj.model_call_details["httpx_response"] = response
@ -2352,7 +2357,13 @@ class BaseLLMHTTPHandler:
self,
e: Exception,
provider_config: Union[
BaseConfig, BaseRerankConfig, BaseResponsesAPIConfig, BaseImageEditConfig, BaseVectorStoreConfig, BaseGoogleGenAIGenerateContentConfig
BaseConfig,
BaseRerankConfig,
BaseResponsesAPIConfig,
BaseImageEditConfig,
BaseVectorStoreConfig,
BaseGoogleGenAIGenerateContentConfig,
BaseAnthropicMessagesConfig,
],
):
status_code = getattr(e, "status_code", 500)
@ -2451,7 +2462,10 @@ class BaseLLMHTTPHandler:
_is_async: bool = False,
fake_stream: bool = False,
litellm_metadata: Optional[Dict[str, Any]] = None,
) -> Union[ImageResponse, Coroutine[Any, Any, ImageResponse],]:
) -> Union[
ImageResponse,
Coroutine[Any, Any, ImageResponse],
]:
"""
Handles image edit requests.
@ -2649,8 +2663,7 @@ class BaseLLMHTTPHandler:
async_httpx_client = client
headers = vector_store_provider_config.validate_environment(
headers=extra_headers or {},
litellm_params=litellm_params
headers=extra_headers or {}, litellm_params=litellm_params
)
if extra_headers:
@ -2661,11 +2674,13 @@ class BaseLLMHTTPHandler:
litellm_params=dict(litellm_params),
)
url, request_body = vector_store_provider_config.transform_search_vector_store_request(
vector_store_id=vector_store_id,
query=query,
vector_store_search_optional_params=vector_store_search_optional_params,
api_base=api_base,
url, request_body = (
vector_store_provider_config.transform_search_vector_store_request(
vector_store_id=vector_store_id,
query=query,
vector_store_search_optional_params=vector_store_search_optional_params,
api_base=api_base,
)
)
logging_obj.pre_call(
@ -2679,7 +2694,9 @@ class BaseLLMHTTPHandler:
)
try:
response = await async_httpx_client.post(url=url, headers=headers, json=request_body, timeout=timeout)
response = await async_httpx_client.post(
url=url, headers=headers, json=request_body, timeout=timeout
)
except Exception as e:
raise self._handle_error(e=e, provider_config=vector_store_provider_config)
@ -2701,7 +2718,9 @@ class BaseLLMHTTPHandler:
timeout: Optional[Union[float, httpx.Timeout]] = None,
client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None,
_is_async: bool = False,
) -> Union[VectorStoreSearchResponse, Coroutine[Any, Any, VectorStoreSearchResponse]]:
) -> Union[
VectorStoreSearchResponse, Coroutine[Any, Any, VectorStoreSearchResponse]
]:
if _is_async:
return self.async_vector_store_search_handler(
vector_store_id=vector_store_id,
@ -2725,8 +2744,7 @@ class BaseLLMHTTPHandler:
sync_httpx_client = client
headers = vector_store_provider_config.validate_environment(
headers=extra_headers or {},
litellm_params=litellm_params
headers=extra_headers or {}, litellm_params=litellm_params
)
if extra_headers:
@ -2737,11 +2755,13 @@ class BaseLLMHTTPHandler:
litellm_params=dict(litellm_params),
)
url, request_body = vector_store_provider_config.transform_search_vector_store_request(
vector_store_id=vector_store_id,
query=query,
vector_store_search_optional_params=vector_store_search_optional_params,
api_base=api_base,
url, request_body = (
vector_store_provider_config.transform_search_vector_store_request(
vector_store_id=vector_store_id,
query=query,
vector_store_search_optional_params=vector_store_search_optional_params,
api_base=api_base,
)
)
logging_obj.pre_call(
@ -2755,7 +2775,9 @@ class BaseLLMHTTPHandler:
)
try:
response = sync_httpx_client.post(url=url, headers=headers, json=request_body)
response = sync_httpx_client.post(
url=url, headers=headers, json=request_body
)
except Exception as e:
raise self._handle_error(e=e, provider_config=vector_store_provider_config)
@ -2785,8 +2807,7 @@ class BaseLLMHTTPHandler:
async_httpx_client = client
headers = vector_store_provider_config.validate_environment(
headers=extra_headers or {},
litellm_params=litellm_params
headers=extra_headers or {}, litellm_params=litellm_params
)
if extra_headers:
@ -2797,9 +2818,11 @@ class BaseLLMHTTPHandler:
litellm_params=dict(litellm_params),
)
url, request_body = vector_store_provider_config.transform_create_vector_store_request(
vector_store_create_optional_params=vector_store_create_optional_params,
api_base=api_base,
url, request_body = (
vector_store_provider_config.transform_create_vector_store_request(
vector_store_create_optional_params=vector_store_create_optional_params,
api_base=api_base,
)
)
logging_obj.pre_call(
@ -2813,7 +2836,9 @@ class BaseLLMHTTPHandler:
)
try:
response = await async_httpx_client.post(url=url, headers=headers, json=request_body, timeout=timeout)
response = await async_httpx_client.post(
url=url, headers=headers, json=request_body, timeout=timeout
)
except Exception as e:
raise self._handle_error(e=e, provider_config=vector_store_provider_config)
@ -2833,7 +2858,9 @@ class BaseLLMHTTPHandler:
timeout: Optional[Union[float, httpx.Timeout]] = None,
client: Optional[Union[HTTPHandler, AsyncHTTPHandler]] = None,
_is_async: bool = False,
) -> Union[VectorStoreCreateResponse, Coroutine[Any, Any, VectorStoreCreateResponse]]:
) -> Union[
VectorStoreCreateResponse, Coroutine[Any, Any, VectorStoreCreateResponse]
]:
if _is_async:
return self.async_vector_store_create_handler(
vector_store_create_optional_params=vector_store_create_optional_params,
@ -2855,8 +2882,7 @@ class BaseLLMHTTPHandler:
sync_httpx_client = client
headers = vector_store_provider_config.validate_environment(
headers=extra_headers or {},
litellm_params=litellm_params
headers=extra_headers or {}, litellm_params=litellm_params
)
if extra_headers:
@ -2867,9 +2893,11 @@ class BaseLLMHTTPHandler:
litellm_params=dict(litellm_params),
)
url, request_body = vector_store_provider_config.transform_create_vector_store_request(
vector_store_create_optional_params=vector_store_create_optional_params,
api_base=api_base,
url, request_body = (
vector_store_provider_config.transform_create_vector_store_request(
vector_store_create_optional_params=vector_store_create_optional_params,
api_base=api_base,
)
)
logging_obj.pre_call(
@ -2883,14 +2911,16 @@ class BaseLLMHTTPHandler:
)
try:
response = sync_httpx_client.post(url=url, headers=headers, json=request_body)
response = sync_httpx_client.post(
url=url, headers=headers, json=request_body
)
except Exception as e:
raise self._handle_error(e=e, provider_config=vector_store_provider_config)
return vector_store_provider_config.transform_create_vector_store_response(
response=response,
)
#####################################################################
################ Google GenAI GENERATE CONTENT HANDLER ###########################
#####################################################################
@ -2918,7 +2948,7 @@ class BaseLLMHTTPHandler:
from litellm.google_genai.streaming_iterator import (
GoogleGenAIGenerateContentStreamingIterator,
)
if _is_async:
return self.async_generate_content_handler(
model=model,
@ -2944,11 +2974,13 @@ class BaseLLMHTTPHandler:
sync_httpx_client = client
# Get headers and URL from the provider config
headers, api_base = generate_content_provider_config.sync_get_auth_token_and_url(
api_base=litellm_params.api_base,
model=model,
litellm_params=dict(litellm_params),
stream=stream,
headers, api_base = (
generate_content_provider_config.sync_get_auth_token_and_url(
api_base=litellm_params.api_base,
model=model,
litellm_params=dict(litellm_params),
stream=stream,
)
)
if extra_headers:
@ -3046,11 +3078,13 @@ class BaseLLMHTTPHandler:
async_httpx_client = client
# Get headers and URL from the provider config
headers, api_base = await generate_content_provider_config.get_auth_token_and_url(
model=model,
litellm_params=dict(litellm_params),
stream=stream,
api_base=litellm_params.api_base,
headers, api_base = (
await generate_content_provider_config.get_auth_token_and_url(
model=model,
litellm_params=dict(litellm_params),
stream=stream,
api_base=litellm_params.api_base,
)
)
if extra_headers: