-
Notifications
You must be signed in to change notification settings - Fork 488
fix(queue): cap dead-letter manual retries to prevent infinite retry loops #223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -110,15 +110,18 @@ export function createQueueRoutes(conversations: Map<string, Conversation>) { | |||||
| }, | ||||||
| failedReason: m.last_error, | ||||||
| attemptsMade: m.retry_count, | ||||||
| manualRetriesUsed: m.manual_retry_count, | ||||||
| manualRetriesRemaining: Math.max(0, 3 - m.manual_retry_count), | ||||||
| timestamp: m.created_at, | ||||||
| }))); | ||||||
| }); | ||||||
|
|
||||||
| // POST /api/queue/dead/:id/retry | ||||||
| app.post('/api/queue/dead/:id/retry', (c) => { | ||||||
| const id = parseInt(c.req.param('id'), 10); | ||||||
| const ok = retryDeadMessage(id); | ||||||
| if (!ok) return c.json({ error: 'dead message not found' }, 404); | ||||||
| const result = retryDeadMessage(id); | ||||||
| if (result === false) return c.json({ error: 'dead message not found' }, 404); | ||||||
| if (result === 'cap_exceeded') return c.json({ error: `Manual retry limit (${3}) reached for this message. Delete it if you want to discard it.` }, 429); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hardcoded literal The template literal
Suggested change
|
||||||
| log('INFO', `[API] Dead message ${id} retried`); | ||||||
| return c.json({ ok: true }); | ||||||
| }); | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Magic number instead of shared constant
manualRetriesRemainingis computed with the literal3rather than a shared constant. BecauseMAX_MANUAL_RETRIESis defined (but not exported) inqueues.ts, this file has no choice but to hardcode the value. If the cap is ever adjusted inqueues.ts, the API response will silently report a stale limit, makingmanualRetriesRemainingwrong for any client that relies on it.The same problem appears on line 124 where the error message uses
${3}— syntactically a template-literal interpolation that always evaluates to the literal3.Fix: Export
MAX_MANUAL_RETRIESfromqueues.tsand import it here:In
packages/core/src/queues.ts:In
packages/server/src/routes/queue.ts:Then replace both occurrences: