Treat HTTP 402 Payment Required as non-retryable in rotation failover

A 402 (e.g. Kilo "usage_limit_exceeded"/out of credits) is deterministic:
retrying the same provider only burns the failure budget and needlessly
disables it within a single request. Add 402 to the non-retryable set so
the rotation fails over to the next provider immediately.
Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
parent ab8f5b69
...@@ -4261,13 +4261,16 @@ class RotationHandler: ...@@ -4261,13 +4261,16 @@ class RotationHandler:
def _is_non_retryable_error(self, error) -> bool: def _is_non_retryable_error(self, error) -> bool:
"""Return True when retrying the same provider for this error is pointless. """Return True when retrying the same provider for this error is pointless.
Client errors that reflect the request/credentials rather than a transient Client errors that reflect the request/credentials/billing rather than a
condition (HTTP 400/401/403/404/405/422) will fail identically on retry, so transient condition (HTTP 400/401/402/403/404/405/422) will fail identically
the rotation should fail over to the next provider immediately. Rate limits on retry, so the rotation should fail over to the next provider immediately.
(408/429) and server/network errors (5xx, timeouts) remain retryable. 402 Payment Required (e.g. Kilo "usage_limit_exceeded"/out of credits) is
Rate-limit handling has its own RateLimitError path and never reaches here. deterministic too: retrying the same provider only burns the failure budget
and needlessly disables it. Rate limits (408/429) and server/network errors
(5xx, timeouts) remain retryable. Rate-limit handling has its own
RateLimitError path and never reaches here.
""" """
non_retryable_codes = {400, 401, 403, 404, 405, 422} non_retryable_codes = {400, 401, 402, 403, 404, 405, 422}
# Prefer the structured status code when the exception carries an HTTP # Prefer the structured status code when the exception carries an HTTP
# response (httpx.HTTPStatusError and similar). # response (httpx.HTTPStatusError and similar).
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment