Commit a750cfb
fix(relay): prevent unbounded recursion in sendTelegram on sustained 429 (koala73#3478)
* fix(relay): prevent unbounded recursion in sendTelegram on sustained 429
The 429 handler in sendTelegram() called itself unconditionally with no
retry counter. Under sustained Telegram rate limiting, this could recurse
indefinitely and crash the Railway relay process.
Changes:
- Add _retryCount parameter (default 0) to sendTelegram()
- Add guard: if (_retryCount ?? 0) >= 1, log and return false immediately
- Pass (_retryCount ?? 0) + 1 on the recursive 429 call (single retry only)
- Non-429 paths (200, 400, 403, 401) are unaffected
Testing:
- Add regression test (static analysis of source, matching repo patterns)
- All 4 new assertions pass: param signature, guard + return false,
incremented recursive call, single call site
- All 27 existing relay tests continue to pass
Fixes koala73#3060
* fix(relay): address review feedback on sendTelegram 429 guard
- Drop redundant `?? 0` — the `_retryCount = 0` default already guarantees
the value is a number inside the function body.
- Cancel the 429 response body on the bail path. Without this the undici
socket can be held open until the body stream is GC'd, which under
sustained rate limiting could pressure the connection pool.
- Replace the static-source-text test with a proper integration test that
invokes `sendTelegram` against a mocked `globalThis.fetch`. The new test
asserts call count and return value across 200, 429→200, sustained 429
(bail), 403, and 401, plus body-cancel hygiene on the bail path. Source
formatting changes that don't alter behaviour will no longer break it.
Required surgery in the relay module:
- Wrap the SIGTERM handler + `subscribe()` invocation in
`if (require.main === module)` so requiring the script from a test does
not start the poll loop.
- Export `{ sendTelegram }` for direct invocation in tests.
The relay's third-party deps (`resend`, `convex/browser`) live in
`scripts/package.json` and are only installed in the Railway container,
so the test stubs them at the loader level via `Module._load`.
All 147 existing relay tests pass; 6 new assertions added.
---------
Co-authored-by: Elie Habib <elie.habib@gmail.com>1 parent b10464e commit a750cfb
2 files changed
Lines changed: 181 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
316 | 316 | | |
317 | 317 | | |
318 | 318 | | |
319 | | - | |
| 319 | + | |
320 | 320 | | |
321 | 321 | | |
322 | 322 | | |
| |||
337 | 337 | | |
338 | 338 | | |
339 | 339 | | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
340 | 345 | | |
341 | 346 | | |
342 | 347 | | |
343 | | - | |
| 348 | + | |
344 | 349 | | |
345 | 350 | | |
346 | 351 | | |
| |||
1100 | 1105 | | |
1101 | 1106 | | |
1102 | 1107 | | |
1103 | | - | |
1104 | | - | |
1105 | | - | |
1106 | | - | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
| 1111 | + | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
| 1118 | + | |
1107 | 1119 | | |
1108 | | - | |
1109 | | - | |
1110 | | - | |
1111 | | - | |
| 1120 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
0 commit comments