From d55ab571a9dc39346aa5ca5d8d0d60cbad51bc33 Mon Sep 17 00:00:00 2001 From: Rodrigo-Palma Date: Fri, 25 Sep 2026 13:52:01 -0300 Subject: [PATCH] test: cover the rebuild that raises The rebuild sits in its own try/except so a failing payload build cannot stop the later callbacks, which is the rule main wrote around the primary build. Nothing asserted that, and the except branch was the one part of this change with no coverage: the test now makes the empty-response retry raise and checks that the success callback still fires. --- .../test_litellm_logging_slo_fallback.py | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/unit/litellm_core_utils/test_litellm_logging_slo_fallback.py b/tests/unit/litellm_core_utils/test_litellm_logging_slo_fallback.py index 16031e93b3f..4410af7ef87 100644 --- a/tests/unit/litellm_core_utils/test_litellm_logging_slo_fallback.py +++ b/tests/unit/litellm_core_utils/test_litellm_logging_slo_fallback.py @@ -132,3 +132,50 @@ async def test_streaming_slo_double_build_failure_is_logged(monkeypatch, caplog) assert logging_obj.model_call_details["standard_logging_object"] is None assert build_calls == [result, {}] assert "rebuild failed" in caplog.text + + +@pytest.mark.asyncio +async def test_streaming_slo_rebuild_raising_does_not_block_callbacks(monkeypatch, caplog): + """The rebuild is wrapped for the same reason main wraps the primary build: + a payload build must never stop the later callbacks from running. If the + empty-response retry raises, the success callback still fires.""" + logging_obj = Logging( + model="claude-3-5-sonnet-20240620", + messages=[{"role": "user", "content": "hi"}], + stream=True, + call_type="anthropic_messages", + start_time=datetime.now(), + litellm_call_id="test-32019-raise", + function_id="test-32019-raise", + ) + build_calls = [] + + def fake_build(self, init_response_obj, start_time, end_time): + build_calls.append(init_response_obj) + if init_response_obj == {}: + raise RuntimeError("rebuild blew up") + return None + + called_back = [] + + async def async_success_callback(kwargs, completion_response, start_time, end_time): + called_back.append(completion_response) + + monkeypatch.setattr(Logging, "_build_standard_logging_payload", fake_build) + monkeypatch.setattr(litellm, "_async_success_callback", [async_success_callback]) + monkeypatch.setattr(litellm, "success_callback", []) + + result = ModelResponse(model="claude-3-5-sonnet-20240620") + + with caplog.at_level(logging.ERROR, logger="LiteLLM"): + await logging_obj.async_success_handler( + result, + start_time=datetime.now(), + end_time=datetime.now(), + cache_hit=False, + ) + + assert build_calls == [result, {}] + assert logging_obj.model_call_details["standard_logging_object"] is None + assert "Exception rebuilding the degraded standard logging payload" in caplog.text + assert len(called_back) == 1