fix: skip DB update in failed handler on intermediate BullMQ retry attempts#92
Conversation
…tempts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Confidence Score: 5/5Safe to merge — the change is a targeted guard in the failed event handler with no impact on the happy path, and the new tests confirm the DB is left untouched on intermediate retries. The guard condition (attemptsMade < opts.attempts ?? 1) is correct for all three cases: intermediate retry (skip DB), final failure (run DB update), and jobs with no retry configured (always run DB update). StorageError is correctly excluded so its custom requeue logic still runs every time. The previous concern about the misleading log on intermediate retries is resolved — the logger.error call now sits below the early return. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["BullMQ 'failed' event fires"] --> B{job defined?}
B -- No --> Z[return]
B -- Yes --> C{err instanceof StorageError?}
C -- Yes --> F["Run StorageError requeue logic"]
C -- No --> D{"attemptsMade < opts.attempts?"}
D -- Yes --> E["logger.warn / return early — DB untouched"]
D -- No --> G["logger.error / updateUploadStatus / clearUploadAccessToken"]
F --> H{requeueCount < MAX?}
H -- Yes --> I["updateStatus queued / removeJob / enqueueUpload"]
H -- No --> G
Reviews (2): Last reviewed commit: "fix: emit warn (not error) for intermedi..." | Re-trigger Greptile |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Fixed — moved the log call inside the handler so intermediate retries now emit — Claude Sonnet 4.6 |
BullMQ fires the
failedevent after every failed attempt, not only the final one. ForSourceCdnErrorandHashLockError(which rely on BullMQ's built-inattempts: 3retry), the handler was callingclearUploadAccessTokenon attempt 1. This left the access token null, so the retry attempt hit the!upload.access_tokenguard and returned without throwing — silently marking the upload asfailedwith 'session expired' instead of retrying the actual CDN error.The fix adds an early return in the
failedhandler whenjob.attemptsMade < job.opts.attemptsand the error is not aStorageError(which has its own custom requeue path and must always run).— Claude Sonnet 4.6