litellm/tests/test_litellm/proxy/common_utils
Refael Iliaguyev e065a2575b
fix(proxy): send a real error event when a /v1/messages stream fails (#41826)
* fix(proxy): send a real error event when a /v1/messages stream fails

When a stream failed halfway through, the proxy wrote the error as a plain
`data: {"error": ...}` line with no `event:` in front of it. Anthropic clients
pick stream events by that name, so they skip the line and the request looks
like it simply stopped with nothing in it.

Write the failure as an `event: error` frame with Anthropic's own payload, and
take the error type from the status code

* fix(proxy): use the shared Anthropic error mapping for the stream error frame

The first pass added a third copy of the status to error-type table, and it
disagreed with the documented one: 529 came out as `api_error` rather than
`overloaded_error`, and 413 as `invalid_request_error` rather than
`request_too_large`, which hides the two failures a client can actually act on.

Drop that copy and put the frame builder next to the table litellm already
keeps in anthropic_interface/exceptions. The bridged adapter path was building
the same frame inline, so it uses the shared one now too

* fix(proxy): seal a torn SSE frame before the /v1/messages error event

An upstream that drops mid-frame leaves the client inside an open event,
so the error frame that follows is glued onto the torn data line and the
Anthropic SDK raises a JSON decode error instead of an APIStatusError.
Close the open frame with a ping event the SDK skips before writing the
error event, and add the e2e stream-cut edge with Bedrock, Anthropic
boundary, and Anthropic mid-frame legs.

* fix(proxy): keep the SSE tail unchanged on a chunk that is not text

A serializer that hands a dict or model object through as-is has no bytes
the frame tail can learn from, so advance_sse_tail leaves it alone instead
of slicing it.

* fix(proxy): answer a /v1/messages stream that fails before its first byte as a JSON error carrying its status

* test: move the Anthropic error frame tests into tests/unit

* test(e2e): cut the upstream stream only after content has been relayed

* test(e2e): carry split SSE lines across chunks and always tear a data line mid-frame

* test(e2e): find the next data line across a chunk boundary before tearing it

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-25 15:36:35 -07:00
..
html_forms test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_admin_ui_utils.py docs: stop advertising sk-1234 as the master key in shipped configs and examples 2026-09-19 12:59:48 -07:00
test_auth_cache_invalidation_pubsub.py fix(caching): propagate auth cache invalidation over Redis Cluster via a node-level pub/sub client (#43110) 2026-09-25 07:56:46 -07:00
test_cache_codec.py fix(proxy): stop CacheCodec dropping null fields on cache round-trip (#32207) 2026-07-06 12:53:00 -07:00
test_callback_config_validation.py feat(arize): per-team success and error sampling rates for the Arize AX callback (#42383) 2026-09-22 11:21:40 -05:00
test_callback_utils.py feat(guardrails): map each guardrail scan id to its guardrail, stage and provider (#40327) 2026-09-08 23:32:31 -07:00
test_config_sync_pubsub.py fix(caching): propagate auth cache invalidation over Redis Cluster via a node-level pub/sub client (#43110) 2026-09-25 07:56:46 -07:00
test_custom_openapi_spec.py fix(proxy): document request body and response schemas for the Responses API in OpenAPI (#42802) 2026-09-24 01:28:34 +00:00
test_debug_utils.py feat(proxy): admin-only /debug/report sharing the bug report environment (#42440) 2026-09-22 12:05:23 -07:00
test_discoverable_model_filter.py feat(proxy): honor model_info.discoverable on the model listing endpoints (#42825) 2026-09-23 17:51:16 -07:00
test_encrypt_decrypt_utils.py fix(proxy): never treat plaintext that base64-decodes to nothing as a ciphertext during the master key migration 2026-09-19 17:53:17 -07:00
test_error_body_call_id.py feat(proxy): opt-in litellm_call_id in JSON error bodies (#42391) 2026-09-21 19:17:18 -07:00
test_expired_ui_session_key_cleanup_manager.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_get_routes.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_http_parsing_utils.py fix(claude_code_gateway): scope the protobuf body skip to the OTLP routes and match the metrics middleware on the route path 2026-09-18 17:23:59 -07:00
test_json_merge_patch.py fix(team): bound json merge patch recursion depth 2026-07-11 09:36:15 -07:00
test_key_rotation_e2e.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_key_rotation_integration.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_key_rotation_lock.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_key_rotation_manager.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_load_config_utils.py fix(proxy): make an ambiguous config include loud, not silent 2026-09-06 03:35:07 -07:00
test_model_deprecation.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_model_listing_utils.py fix(proxy): list key and team model aliases in GET /v1/models (#42908) 2026-09-24 06:41:13 -07:00
test_openai_endpoint_utils.py fix(vector-stores): recurse into nested litellm_params; handle JSON-string shape 2026-04-29 18:56:40 +00:00
test_openai_error_payload.py test: drop the docstring that restated the payload test's name 2026-09-18 22:48:42 -07:00
test_path_utils.py test: require a match= on broad pytest.raises, and drop duplicate parametrize cases (#37769) 2026-08-20 20:24:49 -07:00
test_periodic_reload_schedule.py fix(proxy): persist periodic reload schedule state so status survives restarts and fires without store_model_in_db (#35165) 2026-08-04 15:42:57 -07:00
test_prompt_cache_pricing.py test: delete assertions that pin vendor cost map facts 2026-09-18 00:28:49 +00:00
test_rbac_utils.py test: run the 30 test files stranded in the second mirror (#37595) 2026-08-20 10:59:43 -07:00
test_registry_read_through.py test(proxy): isolate the agent read-through singleton between unknown-agent tests 2026-09-22 01:34:31 +00:00
test_reset_budget_job.py Merge remote-tracking branch 'origin/main' into litellm_lit_3269_project_spend_tracking 2026-09-17 22:29:16 +00:00
test_scheduled_job_stagger.py Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_deflake_20260905 2026-09-09 09:17:41 +00:00
test_sse_keepalive.py fix(proxy): send a real error event when a /v1/messages stream fails (#41826) 2026-09-25 15:36:35 -07:00
test_static_asset_utils.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_swagger_utils.py fix(proxy): make the lazy OpenAPI snapshot byte-identical on every Python version (#42519) 2026-09-22 12:21:20 -07:00
test_timezone_utils.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_upsert_budget_membership.py test(proxy): assert the persisted member budget row as a whole instead of field absence 2026-09-18 02:12:12 +00:00
test_user_api_key_cache.py fix(proxy): apply user_api_key_cache_max_size to the key object partition (#42796) 2026-09-23 17:25:01 -05:00