Skip to content

feat: retry HTTP 408/502/503/504 by default and default max_retries to 3#89

Merged
cosminacho merged 2 commits into
mainfrom
feat/retry-defaults-408-502-and-default-3
May 28, 2026
Merged

feat: retry HTTP 408/502/503/504 by default and default max_retries to 3#89
cosminacho merged 2 commits into
mainfrom
feat/retry-defaults-408-502-and-default-3

Conversation

@ionut-mihalache-uipath
Copy link
Copy Markdown
Collaborator

Summary

  • Adds typed exceptions UiPathRequestTimeoutError (408) and UiPathBadGatewayError (502); registers them in _STATUS_CODE_TO_EXCEPTION, re-exports them from uipath.llm_client.
  • Expands _DEFAULT_RETRY_ON_EXCEPTIONS from {UiPathRateLimitError, UiPathTooManyRequestsError} (HTTP 429, 529) to also include 408, 502, 503, 504. Applies to every provider client because they all share the same UiPathHttpxClient retry transport.
  • Raises the default max_retries from 0 to 3 in both UiPathHttpxClient/UiPathHttpxAsyncClient (when caller passes max_retries=None/omits it) and on UiPathBaseLLMClient.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.
  • Keeps max_retries=0 as the explicit opt-out path so existing callers can still disable retries.
  • Bumps both packages to 1.13.0 and the langchain ↔ core dependency floor to >=1.13.0.

Existing semantics preserved: Retry-After / x-retry-after headers honored, exponential backoff with jitter as fallback, vendor SDKs still receive max_retries=0 so they don't double-retry.

Test plan

  • ruff check on all touched files — clean
  • pyright on touched source files — 0 errors, 0 warnings
  • pytest 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 passed
  • pytest tests/core — 455 passed, 35 skipped, 6 pre-existing unrelated integration errors (Model X not found discovery-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)
  • New regression-lock tests added:
    • tests/core/features/test_httpx_client.py::test_client_default_max_retries_is_three + async variant — pins the new UiPathHttpxClient default
    • tests/core/features/test_httpx_client.py::test_client_explicit_zero_disables_retries + async variant — pins the opt-out path
    • tests/core/features/test_retry.py::TestDefaultRetryOnExceptions — pins the exact set of retried exception types so future PRs can't silently shrink it
    • tests/core/features/test_exceptions.py::test_all_status_code_mappings — extended to include 408 and 502
    • tests/langchain/features/test_default_max_retries.py (new file) — pins the LangChain-side default and opt-out on UiPathBaseLLMClient

🤖 Generated with Claude Code

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 cosminacho merged commit 3c8ebcc into main May 28, 2026
11 checks passed
@cosminacho cosminacho deleted the feat/retry-defaults-408-502-and-default-3 branch May 28, 2026 10:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants