Add a per-request timeout guard
Description
src/index.ts has no upper bound on how long a request may take. Every current handler is synchronous, but the codebase is explicitly heading toward async work (webhook delivery, persistence, a settlement worker fan-out), and the deep-health README already promises a "5s timeout via AbortController" that the synchronous code does not actually enforce. A single slow or hung downstream call would tie up the connection indefinitely. This issue adds a global request-timeout middleware that responds with a canonical error if a handler exceeds a configurable deadline.
Requirements and context
- Repository scope: StableRoute-Org/Stableroute-backend only.
- Add middleware that arms a timer (default from
REQUEST_TIMEOUT_MS, e.g. 10s) and, if the response has not finished in time, sends 503 request_timeout with the canonical { error, message, requestId } body.
- Clear the timer on
res.on("finish")/close so completed requests do not leak timers.
- Guard against double-send: if headers are already sent, log and skip rather than throwing.
- Make the timeout tunable via
config/env so tests can use a tiny value deterministically.
Suggested execution
- Fork the repo and create a branch
git checkout -b security/resilience-30-request-timeout
- Implement changes
- Write code in:
src/index.ts — add the timeout middleware near the top of the chain.
- Write comprehensive tests in:
src/__tests__/index.test.ts — mount a deliberately slow test route with a tiny timeout and assert the 503 request_timeout shape; assert a fast route is unaffected and leaves no dangling timer.
- Add documentation: document
REQUEST_TIMEOUT_MS in README.md.
- Add TSDoc on the middleware.
- Validate security: ensure the timer is always cleared and cannot fire after a response was sent.
- Test and commit
Test and commit
- Run
npm run build, npm run lint, and npm test.
- Cover edge cases: handler within deadline, handler exceeding deadline, double-finish.
- Paste the full
npm test output in the PR.
Example commit message
feat(resilience): add per-request timeout guard returning 503
Guidelines
- Minimum 95 percent test coverage for impacted code.
- Clear, reviewer-focused documentation.
- Timeframe: 96 hours.
Community & contribution rewards
- 💬 Join the StableRoute community on Discord for questions, reviews, and faster merges: https://discord.gg/37aCpusvx
- ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project — if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward.
Add a per-request timeout guard
Description
src/index.tshas no upper bound on how long a request may take. Every current handler is synchronous, but the codebase is explicitly heading toward async work (webhook delivery, persistence, a settlement worker fan-out), and the deep-health README already promises a "5s timeout via AbortController" that the synchronous code does not actually enforce. A single slow or hung downstream call would tie up the connection indefinitely. This issue adds a global request-timeout middleware that responds with a canonical error if a handler exceeds a configurable deadline.Requirements and context
REQUEST_TIMEOUT_MS, e.g. 10s) and, if the response has not finished in time, sends503 request_timeoutwith the canonical{ error, message, requestId }body.res.on("finish")/closeso completed requests do not leak timers.config/env so tests can use a tiny value deterministically.Suggested execution
git checkout -b security/resilience-30-request-timeoutsrc/index.ts— add the timeout middleware near the top of the chain.src/__tests__/index.test.ts— mount a deliberately slow test route with a tiny timeout and assert the503 request_timeoutshape; assert a fast route is unaffected and leaves no dangling timer.REQUEST_TIMEOUT_MSinREADME.md.Test and commit
npm run build,npm run lint, andnpm test.npm testoutput in the PR.Example commit message
feat(resilience): add per-request timeout guard returning 503Guidelines
Community & contribution rewards