#7615: fix(gateway): add request timeout to GatewayClient
gateway
Cluster:
Timeouts and Memory Management Fixes
## 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
#6302: fix: Add timeouts to prevent indefinite hangs (issues #4954, #4956,...
by batumilove · 2026-02-01
82.7%
#6466: fix(gateway): add handshake timeout and connection error handling
by jarvis-raven · 2026-02-01
80.7%
#18221: fix(cli): raise cron command timeout to 90s and retry read-only RPCs
by BinHPdev · 2026-02-16
79.1%
#9178: Fix: GatewayClient queueConnect() setTimeout never fires
by vishaltandale00 · 2026-02-04
77.2%
#10636: fix: setTimeout integer overflow causing server crash
by devmangel · 2026-02-06
75.6%
#12477: fix(agents): prevent TimeoutOverflowWarning when timeout is disabled
by skylarkoo7 · 2026-02-09
75.4%
#11874: fix: handle fetch rejections in provider usage withTimeout
by Zjianru · 2026-02-08
74.8%
#16963: fix: enable auth rate limiting by default
by StressTestor · 2026-02-15
74.6%
#4653: fix(gateway): improve crash resilience for mDNS and network errors
by AyedAlmudarra · 2026-01-30
74.3%
#17678: fix(gateway): expose timeoutMs in readJsonBody to prevent Slowloris...
by mcrolly · 2026-02-16
74.1%