feat: retry HTTP 408/502/503/504 by default and default max_retries to 3#89
Merged
Merged
Conversation
Expands the default retry-on set in uipath.llm_client.utils.retry from
{429, 529} to {408, 429, 502, 503, 504, 529} and adds the two new
exception classes (UiPathRequestTimeoutError, UiPathBadGatewayError)
needed to type 408/502 responses. Raises the default max_retries in
UiPathHttpxClient/UiPathHttpxAsyncClient (when left as None) and on
UiPathBaseLLMClient from 0 to 3, so every provider (OpenAI, Anthropic
in all four flavors, Google, all three LangChain Bedrock variants,
Vertex AI, Azure OpenAI, Fireworks, LiteLLM) retries transient failures
out of the box. Callers can still opt out by passing max_retries=0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds TestRetryOn504EndToEnd which drives a real request through RetryableHTTPTransport / RetryableAsyncHTTPTransport and asserts the underlying call fires max_retries times before the final 504 response is returned. The existing tests only covered configuration/wiring, not the actual retry loop behavior against a real httpx.Response. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cosminacho
approved these changes
May 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
UiPathRequestTimeoutError(408) andUiPathBadGatewayError(502); registers them in_STATUS_CODE_TO_EXCEPTION, re-exports them fromuipath.llm_client._DEFAULT_RETRY_ON_EXCEPTIONSfrom{UiPathRateLimitError, UiPathTooManyRequestsError}(HTTP 429, 529) to also include 408, 502, 503, 504. Applies to every provider client because they all share the sameUiPathHttpxClientretry transport.max_retriesfrom0to3in bothUiPathHttpxClient/UiPathHttpxAsyncClient(when caller passesmax_retries=None/omits it) and onUiPathBaseLLMClient.max_retries. Every LangChain chat/embeddings client (OpenAI, Anthropic in all four flavors, Google/Gemini, all three Bedrock variants, Vertex AI, Azure, Fireworks, LiteLLM) now retries 3 times by default.max_retries=0as the explicit opt-out path so existing callers can still disable retries.>=1.13.0.Existing semantics preserved:
Retry-After/x-retry-afterheaders honored, exponential backoff with jitter as fallback, vendor SDKs still receivemax_retries=0so they don't double-retry.Test plan
ruff checkon all touched files — cleanpyrighton touched source files — 0 errors, 0 warningspytest tests/core/features/test_exceptions.py tests/core/features/test_retry.py tests/core/features/test_httpx_client.py tests/core/smoke_test.py tests/langchain/features/test_default_max_retries.py tests/langchain/features/test_default_headers_merge.py— 98 passedpytest tests/core— 455 passed, 35 skipped, 6 pre-existing unrelated integration errors (Model X not founddiscovery-list mismatch in litellm tests)pytest tests/langchain— 1316 passed, 28 pre-existing failures, 188 pre-existing errors (all expired token / discovery-list / live-model-determinism, none caused by this change — verified by inspecting tracebacks of the failing tests)tests/core/features/test_httpx_client.py::test_client_default_max_retries_is_three+ async variant — pins the newUiPathHttpxClientdefaulttests/core/features/test_httpx_client.py::test_client_explicit_zero_disables_retries+ async variant — pins the opt-out pathtests/core/features/test_retry.py::TestDefaultRetryOnExceptions— pins the exact set of retried exception types so future PRs can't silently shrink ittests/core/features/test_exceptions.py::test_all_status_code_mappings— extended to include 408 and 502tests/langchain/features/test_default_max_retries.py(new file) — pins the LangChain-side default and opt-out onUiPathBaseLLMClient🤖 Generated with Claude Code