mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
fix(router): ignore non-integer status codes when picking retry skips
CI's router_code_coverage gate wants every function in router.py called by name from a test file with "router" in its name, and the new helper had no direct caller, so the check-quality job failed on the first tip. Covering it directly also turned up a hole. litellm._should_retry compares the status code to 500, so a provider exception carrying a string status code raises TypeError instead of answering. should_retry_this_error has the same call, but the retry policy path skips it, which is exactly the path this change enables, so the helper was the first to touch that value. Narrowing to int leaves those exceptions on the old retry-in-place behavior.
This commit is contained in:
parent
2e2fce5e58
commit
7c7810df42
2 changed files with 28 additions and 1 deletions
|
|
@ -7467,7 +7467,7 @@ class Router:
|
|||
) -> tuple[str, ...]:
|
||||
failed_deployment_id: Final[str | None] = getattr(exception, "failed_deployment_id", None)
|
||||
status_code: Final = getattr(exception, "status_code", None)
|
||||
if not failed_deployment_id or status_code is None:
|
||||
if not failed_deployment_id or not isinstance(status_code, int):
|
||||
return ()
|
||||
if litellm._should_retry(status_code): # pyright: ignore[reportPrivateUsage] # as in should_retry_this_error
|
||||
return ()
|
||||
|
|
|
|||
|
|
@ -13234,6 +13234,33 @@ async def test_router_retry_policy_400_retries_on_sibling_deployment(
|
|||
assert response._hidden_params["additional_headers"]["x-litellm-attempted-retries"] == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"status_code,failed_deployment_id,already_skipped,healthy_deployment_ids,expected",
|
||||
[
|
||||
(400, "rejecting", None, ["rejecting", "accepting"], ("rejecting",)),
|
||||
(403, "rejecting", None, ["rejecting", "accepting"], ("rejecting",)),
|
||||
(400, "second", ("first",), ["first", "second", "third"], ("first", "second")),
|
||||
(429, "rejecting", None, ["rejecting", "accepting"], ()),
|
||||
(503, "rejecting", None, ["rejecting", "accepting"], ()),
|
||||
(400, "rejecting", None, ["rejecting"], ()),
|
||||
(400, None, None, ["rejecting", "accepting"], ()),
|
||||
(None, "rejecting", None, ["rejecting", "accepting"], ()),
|
||||
("400", "rejecting", None, ["rejecting", "accepting"], ()),
|
||||
],
|
||||
)
|
||||
def test_router_deployment_ids_to_skip_on_retry(
|
||||
status_code, failed_deployment_id, already_skipped, healthy_deployment_ids, expected
|
||||
):
|
||||
exception = Exception("upstream refused this request")
|
||||
exception.status_code = status_code
|
||||
exception.failed_deployment_id = failed_deployment_id
|
||||
healthy_deployments = [{"model_info": {"id": deployment_id}} for deployment_id in healthy_deployment_ids]
|
||||
|
||||
assert (
|
||||
litellm.Router._deployment_ids_to_skip_on_retry(exception, already_skipped, healthy_deployments) == expected
|
||||
)
|
||||
|
||||
|
||||
def _make_failure_logging_obj():
|
||||
return LiteLLMLogging(
|
||||
model="gpt-5.6",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue