Skip to content

fix: retry connection errors in the interactions client - #3205

Open
fcakyon wants to merge 1 commit into
googleapis:mainfrom
fcakyon:fix-interactions-transport-retries
Open

fcakyon wants to merge 1 commit into
googleapis:mainfrom
fcakyon:fix-interactions-transport-retries

Conversation

@fcakyon

@fcakyon fcakyon commented Oct 23, 2026

Copy link
Copy Markdown

Fixes #3204.

client.interactions never retries httpx.ConnectError or other transport failures, even though _translate_retry_config sets retry_connection_errors=True. CompatErrorHook.after_error runs inside the per-attempt do() in BaseSDK.do_request and turns the httpx error into APIConnectionError. _is_transport_error in the generated retries.py does not recognize that type, so the retry loop raises it as a PermanentError on the first attempt.

  • after_error now returns errors unchanged. Translation happens once, at the public boundary, in wrap_sdk_call / async_wrap_sdk_call, which the bridge methods already call (raw and streaming responses go through _RawResponseAccessorProxy). Callers still get APIConnectionError / APITimeoutError with the httpx error as __cause__.
  • environments.files.upload was the one bridge path that called generated code (self._internal.start_upload, sync and async) without wrap_sdk_call. It is wrapped now, so it keeps raising APIConnectionError.
  • Both changes are in hand-maintained files, since basesdk.py and retries.py are Speakeasy output.
  • With HttpRetryOptions(attempts=3) and a transport that always raises ConnectError: 1 attempt before, 4 after, the same as a 503. Sync, async, and the httpx2 client all behave this way.
  • Behavior change: _translate_retry_config defaults to 3 retries when retry_options is unset, so default clients now retry connection errors and timeouts (httpx.TimeoutException) too. The models path already retries these when HttpRetryOptions is set (fix(retry): retry on httpx.TimeoutException with HttpRetryOptions #2345, fix: Honor HttpRetryOptions for aiohttp connection errors in async requests #3186).
  • New tests in test_httpx_compat.py: the sync and async interactions tests fail on main (assert 1 > 1), and the upload test fails without the new wrap_sdk_call (raw httpx.ConnectError).
-        if error is None:
-            return response, error
-        return response, wrap_sdk_error(error)  # type: ignore[return-value]
+        # Runs once per attempt inside the retry loop, which only retries raw
+        # httpx errors, so `wrap_sdk_call` translates after the last attempt.
+        return response, error

CompatErrorHook wrapped httpx errors before the retry loop checked them.
@google-cla

google-cla Bot commented Oct 23, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@fcakyon fcakyon changed the title Retry connection errors in the interactions client fix: retry connection errors in the interactions client Oct 23, 2026

This branch has not been deployed

No deployments
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.

Interactions API does not retry connection errors despite HttpRetryOptions

1 participant