feat(http): add configurable request timeout - #131
Conversation
The Guzzle clients in API and SDKConfig were constructed with no timeout options, so requests could hang indefinitely (bounded in practice only by PHP's default_socket_timeout). This adds a single `requestTimeout` config knob matching the Go and Python SDKs, applied as a default option at client construction alongside a built-in 10s connect timeout. Defaults: 60s request, 10s connect. An optional `httpClient` may also be supplied; when present the SDK uses it verbatim and does not override its transport configuration. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
🐕 Review complete — View session on Shuni Portal 🐾 |
🐕 Suggested ReviewersThe review assignment prioritizes contributors with broad involvement in core SDK files and testing, ensuring comprehensive evaluation of the new configurable request timeout feature.
Suggested by Shuni based on git history and PR context. Names are not @-mentioned to avoid notifying anyone — request a review from whoever fits best. |
There was a problem hiding this comment.
🐕 Shuni's Review
Adds a single requestTimeout config option (default 60s) plus a built-in 10s connect timeout, bounding every SDK HTTP call, with optional httpClient passthrough.
No issues found — good bones! Traced all paths: array-union client options, API import in SDKConfig, resolveRequestTimeout validation (rejects bool/0/negative/non-numeric, guards INF/NAN), and injected-client verbatim passthrough all check out. New constructor params are optional → backward compatible, and tests match the implementation. Woof!
Fixes: https://github.com/descope/etc/issues/17203
What changed
Adds a single
requestTimeoutconfig option (seconds, default 60) that bounds every HTTP call the SDK makes, plus a built-in 10s connection-establishment timeout. An optionalhttpClientcan be supplied for full transport control.Why
Both Guzzle clients (
APIandSDKConfig) were built withnew Client()and no timeout options, so a slow or unresponsive peer could hang a PHP worker indefinitely — bounded in practice only by PHP'sdefault_socket_timeout. The JWKS fetch inSDKConfigwas fully unbounded.Design — parity with the sibling SDKs
This intentionally matches the single-knob design shared by the Go SDK (
RequestTimeout) and Python SDK (timeout_seconds) rather than introducing a larger surface. The timeout is applied as a default option at client construction, soexecuteWithRetryand the request methods are unchanged. Retry semantics stay per-attempt, consistent with Go/Python.requestTimeoutaccepts a positive int/float/numeric-string; invalid values throwInvalidArgumentException.httpClient, the SDK uses it verbatim and does not override its timeouts.Tests
New
APIHttpTimeoutTest(12 tests) covering defaults, configured values, injected-client passthrough, and validation. Full suite: 94 passing.Supersedes #130
Replaces #130 with a lighter design that stays consistent across the Descope SDK family. Also fixes a bug in that PR where an injected client's own timeouts were overridden. The one idea from #130 not carried over is a separate
managementRequestTimeout— left out for cross-SDK parity; can be revisited if there's demand.🤖 Generated with Claude Code