Skip to content

fix(serverless-offline-sqs): isolate poll-loop receive failures so they don't kill the process (Fixes #226)#290

Merged
silouone merged 1 commit into
masterfrom
fix/sqs-poll-loop-error-isolation
Jun 21, 2026
Merged

fix(serverless-offline-sqs): isolate poll-loop receive failures so they don't kill the process (Fixes #226)#290
silouone merged 1 commit into
masterfrom
fix/sqs-poll-loop-error-isolation

Conversation

@silouone

Copy link
Copy Markdown
Member

Fixes #226

What / why

Reported by @newtechfellas: uncaught errors in the SQS poll loop terminate the serverless offline Node process, unlike API Gateway handler errors. Handler throws were already isolated (the #265 threaded-logger work), but the poll loop still had two leak paths: the ReceiveMessage long-poll (getMessages()) sat outside job()'s try/catch, and the re-enqueue this.queue.add(job) was a floating promise never .catch()ed. p-queue rejects that promise when the task throws, so a transient SQS-client / network failure during receive became an unhandled promise rejection that killed the process.

This moves getMessages() inside the try (a receive failure is now logged via log.warning and the loop re-schedules, exactly like a thrown handler) and routes both enqueue calls through a new pure, exported enqueueLoop(queue, task, log) helper that .catch()es the p-queue task into the injected logger. Happy-path delivery (receive → run handler → delete batch) is byte-for-byte unchanged.

Credit

Thanks to @newtechfellas for the report.

Verification

Failing AVA repro written first (2 unhandled rejections, warnings.length === 0) and confirmed to FAIL on origin/master. After the fix: npx ava packages/serverless-offline-sqs/test/index.js124 passed (7 new #226 tests), npx eslint clean. Independently re-run by the orchestrator: green. All unit-level (AWS client mocked); no docker.

Reviewer note (non-blocking, out of scope)

Under a persistent connection-refused emulator, the loop now warns in a tight busy-loop (no back-off). Strictly safer than master's process termination; an inter-poll back-off is a possible follow-up.

🤖 Generated with Claude Code

…ey don't kill the process (Fixes #226)

A transient ReceiveMessage/SQS-client failure escaped the job() try/catch and
the floating queue.add(job) promise went unhandled, terminating serverless
offline. Move getMessages() inside the try and re-enqueue through a new pure
enqueueLoop helper that .catch()es the p-queue task into log.warning.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@silouone silouone marked this pull request as ready for review June 21, 2026 08:12
@silouone silouone merged commit fe63622 into master Jun 21, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[serverless-offline-sqs] Uncaught exceptions from SQS handler functions terminates nodejs process

1 participant