mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-10 22:41:41 +00:00
fix(http_handler): surface BaseLLMException raised while streaming a request body
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
0b33da566a
commit
2b14762d0f
2 changed files with 64 additions and 3 deletions
|
|
@ -44,7 +44,7 @@ from litellm.llms.base_llm.base_model_iterator import (
|
|||
MockResponseIterator,
|
||||
)
|
||||
from litellm.llms.base_llm.batches.transformation import BaseBatchesConfig
|
||||
from litellm.llms.base_llm.chat.transformation import BaseConfig
|
||||
from litellm.llms.base_llm.chat.transformation import BaseConfig, BaseLLMException
|
||||
from litellm.llms.base_llm.containers.transformation import BaseContainerConfig
|
||||
from litellm.llms.base_llm.embedding.transformation import BaseEmbeddingConfig
|
||||
from litellm.llms.base_llm.evals.transformation import BaseEvalsAPIConfig
|
||||
|
|
@ -311,6 +311,24 @@ def _collect_ws_project_quota_callbacks() -> tuple[ProjectQuotaCallback, ...]:
|
|||
)
|
||||
|
||||
|
||||
def _find_base_llm_exception(error: BaseException, depth: int = 0) -> BaseLLMException | None:
|
||||
if depth >= 10:
|
||||
return None
|
||||
if isinstance(error, BaseLLMException):
|
||||
return error
|
||||
|
||||
cause: Final = error.__cause__
|
||||
if cause is not None:
|
||||
provider_exception: Final = _find_base_llm_exception(cause, depth + 1)
|
||||
if provider_exception is not None:
|
||||
return provider_exception
|
||||
|
||||
context: Final = error.__context__
|
||||
if context is not None:
|
||||
return _find_base_llm_exception(context, depth + 1)
|
||||
return None
|
||||
|
||||
|
||||
class BaseLLMHTTPHandler:
|
||||
async def _make_common_async_call(
|
||||
self,
|
||||
|
|
@ -5980,6 +5998,10 @@ class BaseLLMHTTPHandler:
|
|||
BaseEvalsAPIConfig,
|
||||
],
|
||||
):
|
||||
provider_exception: Final = _find_base_llm_exception(e)
|
||||
if provider_exception is not None:
|
||||
raise provider_exception
|
||||
|
||||
received_status_code: Final = (
|
||||
e.response.status_code if isinstance(e, httpx.HTTPStatusError) else getattr(e, "status_code", None)
|
||||
)
|
||||
|
|
@ -6000,8 +6022,6 @@ class BaseLLMHTTPHandler:
|
|||
error_headers = {}
|
||||
|
||||
if provider_config is None:
|
||||
from litellm.llms.base_llm.chat.transformation import BaseLLMException
|
||||
|
||||
raise BaseLLMException(
|
||||
status_code=status_code,
|
||||
message=error_text,
|
||||
|
|
|
|||
|
|
@ -2110,6 +2110,47 @@ def test_sync_retrieve_file_content_raises_on_http_error():
|
|||
assert exc_info.value.status_code == 404
|
||||
|
||||
|
||||
def test_handle_error_preserves_base_llm_exception_message_and_status():
|
||||
from litellm.llms.vertex_ai.common_utils import VertexAIError
|
||||
from litellm.llms.vertex_ai.files.transformation import VertexAIFilesConfig
|
||||
|
||||
message = "Invalid JSON on line 3 of batch input file: Expecting value"
|
||||
error = VertexAIError(status_code=400, message=message)
|
||||
|
||||
with pytest.raises(VertexAIError) as exc_info:
|
||||
BaseLLMHTTPHandler()._handle_error(e=error, provider_config=VertexAIFilesConfig())
|
||||
|
||||
assert exc_info.value.status_code == 400
|
||||
assert exc_info.value.message == message
|
||||
|
||||
|
||||
def test_handle_error_preserves_base_llm_exception_from_wrapper():
|
||||
from litellm.llms.vertex_ai.common_utils import VertexAIError
|
||||
from litellm.llms.vertex_ai.files.transformation import VertexAIFilesConfig
|
||||
|
||||
message = "Invalid JSON on line 3 of batch input file: Expecting value"
|
||||
error = VertexAIError(status_code=400, message=message)
|
||||
wrapper = httpx.ConnectError("Failed to send bytes")
|
||||
wrapper.__cause__ = error
|
||||
|
||||
with pytest.raises(VertexAIError) as exc_info:
|
||||
BaseLLMHTTPHandler()._handle_error(e=wrapper, provider_config=VertexAIFilesConfig())
|
||||
|
||||
assert exc_info.value.status_code == 400
|
||||
assert exc_info.value.message == message
|
||||
|
||||
|
||||
def test_handle_error_maps_plain_exception_to_provider_error():
|
||||
from litellm.llms.vertex_ai.common_utils import VertexAIError
|
||||
from litellm.llms.vertex_ai.files.transformation import VertexAIFilesConfig
|
||||
|
||||
with pytest.raises(VertexAIError) as exc_info:
|
||||
BaseLLMHTTPHandler()._handle_error(e=ValueError("boom"), provider_config=VertexAIFilesConfig())
|
||||
|
||||
assert exc_info.value.status_code == 500
|
||||
assert exc_info.value.message == "boom"
|
||||
|
||||
|
||||
_UPSTREAM_NOT_FOUND_BODY = {
|
||||
"error": {
|
||||
"message": "Response with id 'resp_abc' not found.",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue