mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-25 01:02:15 +00:00
fix(responses): import BaseLLMException lazily and collect stream chunks via anext
Move the BaseLLMException import into _map_error_event_exception so the
module no longer imports it at load time, clearing the module-level cyclic
import CodeQL flagged. The class is used only on the cold error path.
Replace the mutable list-append test collector with aiter/anext so the
regression tests read the stream immutably.
(cherry picked from commit c246372859)
This commit is contained in:
parent
80b2c803bd
commit
2e44af6d20
2 changed files with 11 additions and 14 deletions
|
|
@ -29,7 +29,6 @@ from litellm.litellm_core_utils.llm_response_utils.response_metadata import (
|
|||
update_response_metadata,
|
||||
)
|
||||
from litellm.litellm_core_utils.thread_pool_executor import executor
|
||||
from litellm.llms.base_llm.chat.transformation import BaseLLMException
|
||||
from litellm.llms.base_llm.responses.transformation import BaseResponsesAPIConfig
|
||||
from litellm.responses.utils import ResponseAPILoggingUtils, ResponsesAPIRequestUtils
|
||||
from litellm.types.llms.openai import (
|
||||
|
|
@ -496,6 +495,8 @@ class BaseResponsesAPIStreamingIterator:
|
|||
)
|
||||
|
||||
def _map_error_event_exception(self, error_obj: object) -> Exception:
|
||||
from litellm.llms.base_llm.chat.transformation import BaseLLMException
|
||||
|
||||
error_message, error_type, error_code = _error_event_fields(error_obj)
|
||||
status_code: Final = _status_code_for_error_fields(error_type, error_code)
|
||||
error_body: Final = {"message": error_message, "type": error_type, "code": error_code}
|
||||
|
|
|
|||
|
|
@ -286,15 +286,12 @@ async def test_async_iterator_content_policy_violation_after_first_chunk_carries
|
|||
]
|
||||
)
|
||||
|
||||
chunks = []
|
||||
|
||||
async def _drain():
|
||||
async for chunk in iterator:
|
||||
chunks.append(chunk)
|
||||
stream = aiter(iterator)
|
||||
first_chunk = await anext(stream)
|
||||
assert first_chunk is not None
|
||||
|
||||
with pytest.raises(MidStreamFallbackError) as exc_info:
|
||||
await _drain()
|
||||
assert len(chunks) == 1
|
||||
await anext(stream)
|
||||
assert isinstance(exc_info.value.original_exception, litellm.ContentPolicyViolationError)
|
||||
assert exc_info.value.is_pre_first_chunk is False
|
||||
assert exc_info.value.generated_content == "partial "
|
||||
|
|
@ -315,14 +312,13 @@ async def test_async_iterator_error_after_first_chunk_carries_generated_content(
|
|||
]
|
||||
)
|
||||
|
||||
chunks = []
|
||||
async def _drain():
|
||||
async for chunk in iterator:
|
||||
chunks.append(chunk)
|
||||
stream = aiter(iterator)
|
||||
first_chunk = await anext(stream)
|
||||
second_chunk = await anext(stream)
|
||||
assert first_chunk is not None and second_chunk is not None
|
||||
|
||||
with pytest.raises(MidStreamFallbackError) as exc_info:
|
||||
await _drain()
|
||||
assert len(chunks) == 2
|
||||
await anext(stream)
|
||||
assert exc_info.value.status_code == 500
|
||||
assert exc_info.value.is_pre_first_chunk is False
|
||||
assert exc_info.value.generated_content == "hello world"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue