Skip to content

fix: add configurable HTTP timeout and preserve error context#318

Open
skyc1e wants to merge 1 commit intoPolymarket:mainfrom
skyc1e:fix/configurable-http-timeout
Open

fix: add configurable HTTP timeout and preserve error context#318
skyc1e wants to merge 1 commit intoPolymarket:mainfrom
skyc1e:fix/configurable-http-timeout

Conversation

@skyc1e
Copy link
Copy Markdown

@skyc1e skyc1e commented Apr 1, 2026

Summary

Fixes #273.

The default httpx timeout (~5s) causes silent order duplication under load: requests time out client-side, the SDK raises a generic PolyApiException, callers assume failure and retry, but the original order was already matched server-side. Multiple users reported duplicate fills from this behavior.

Changes

  • Added optional timeout parameter to ClobClient.__init__() — when provided, reconfigures the module-level httpx client with the specified timeout in seconds
  • Preserved the original httpx.RequestError via exception chaining (raise ... from exc) so callers can distinguish timeouts from DNS failures, connection resets, etc.
  • Fully backward compatible: default behavior unchanged when timeout is not specified

Usage

client = ClobClient(
    host="https://clob.polymarket.com",
    key=key,
    chain_id=137,
    timeout=30,
)

Test plan

  • Verified default behavior unchanged (no timeout arg = httpx default)
  • Verified timeout=30 reconfigures the client correctly
  • Verified exception chaining preserves original error type and message

Note

Medium Risk
Changes HTTP client configuration and error propagation for all SDK requests, which could alter runtime behavior (timeouts) and exception handling in consumers.

Overview
Adds an optional timeout argument to ClobClient.__init__ that reconfigures the module-level httpx client via new set_http_timeout, allowing callers to override default request timeouts.

Improves HTTP error reporting by including the original httpx.RequestError message and chaining the exception (raise ... from exc) so consumers can distinguish timeouts and connection failures.

Written by Cursor Bugbot for commit b69208f. This will update automatically on new commits. Configure here.

The default httpx timeout (~5s) causes silent order duplication when
the server is slow under load: requests time out client-side, the SDK
raises a generic PolyApiException, callers retry, but the original
order was already matched server-side.

Add an optional timeout parameter to ClobClient so users can increase
the HTTP timeout for their use case (e.g. timeout=30 for volatile
markets). Also chain the original httpx exception so callers can
distinguish timeouts from connection errors.

Closes Polymarket#273
@skyc1e skyc1e requested a review from a team as a code owner April 1, 2026 02:25
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reconfigure the module-level HTTP client with a custom timeout (in seconds).
"""
global _http_client
_http_client = httpx.Client(http2=True, timeout=timeout)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old HTTP client not closed, leaking connections

Medium Severity

set_http_timeout replaces the module-level _http_client with a new httpx.Client without calling .close() on the old one. Since the client is created with http2=True, the old instance holds open HTTP/2 connections and associated resources (sockets, TLS state) that are never properly released, causing a resource leak.

Fix in Cursor Fix in Web

self.mode = self._get_client_mode()

if timeout is not None:
set_http_timeout(timeout)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per-instance timeout parameter actually mutates global state

High Severity

The timeout parameter on ClobClient.__init__ suggests per-instance configuration, but set_http_timeout replaces a module-level global _http_client shared by all instances. Creating a second ClobClient with a different (or no) timeout silently overrides the first client's timeout. Ironically, this can reintroduce the exact duplicate-order problem the PR aims to fix — a user sets timeout=30 on one client, then another component instantiates a default client, resetting the timeout to httpx's default.

Additional Locations (1)
Fix in Cursor Fix in Web

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.

PolyApiException[status_code=None, error_message=Request exception!] - 5s timeout but matched/filled.

1 participant