← Back to PRs

#7615: fix(gateway): add request timeout to GatewayClient

by alamine42 open 2026-02-03 01:25 View on GitHub →
gateway
## Summary - Adds configurable timeout to `GatewayClient.request()` method - Prevents requests from hanging indefinitely (CWE-400) - Default timeout: 30 seconds (configurable, set to 0 to disable) Fixes #4954 ## Changes - New `GatewayTimeoutError` class for timeout-specific error handling - `timeout` option in `GatewayClientOptions` for client-level default - `timeout` option in `request()` method for per-request override - `requestTimeout` config option in `GatewayConfig` and `GatewayRemoteConfig` ## Implementation Uses `Promise.race` with `setTimeout` to race the request promise against a timeout. On timeout: 1. Clears the pending request from the map 2. Throws `GatewayTimeoutError` with method name and timeout duration 3. Cleans up the timeout timer in `finally` block ## Test plan - [x] Request times out after configured duration - [x] Per-request timeout overrides client-level timeout - [x] Timeout of 0 disables timeout - [x] Successful request clears timeout properly - [x] All existing tests pass ## Configuration \`\`\`yaml # Client-level default (in code) const client = new GatewayClient({ timeout: 30000, // 30 seconds, or 0 to disable }); # Per-request override await client.request("method", params, { timeout: 5000 }); # Config file gateway: requestTimeout: 30000 \`\`\` 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds request-level timeouts to `GatewayClient.request()` via a `Promise.race` against a `setTimeout`, introduces a `GatewayTimeoutError` for callers to detect timeouts, and threads new `requestTimeout` config fields through gateway config types. The accompanying tests exercise default vs per-request timeout behavior and disabling timeouts. This fits into the existing Gateway client model where requests are tracked in an in-memory `pending` map keyed by request id and resolved/rejected when response frames arrive; the timeout path now deletes the pending entry to prevent indefinite growth when responses never arrive. <h3>Confidence Score: 4/5</h3> - This PR is largely safe to merge; changes are localized and covered by tests. - Core timeout behavior is implemented correctly for preventing indefinite waits and cleaning up the `pending` map/timer. Main concern is semantic: timeouts don’t cancel in-flight server work and late responses are dropped, which could surprise callers for non-idempotent methods. Test scaffolding has a minor fragility pattern but should not affect production. - src/gateway/client.ts (timeout semantics) and src/gateway/client.test.ts (test setup robustness). <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs