Skip to content

feat: Add Dead-Letter Queue for Poison Messages - #4

Merged
ThomasHartDev merged 2 commits into
mainfrom
thomas/feat/dead-letter
Aug 16, 2026
Merged

feat: Add Dead-Letter Queue for Poison Messages#4
ThomasHartDev merged 2 commits into
mainfrom
thomas/feat/dead-letter

Conversation

@ThomasHartDev

Copy link
Copy Markdown
Owner

A handler that always throws used to abort the rest of a fan-out. This adds a DeadLetterQueue and a withDeadLetter wrapper that retries the failed handler immediately on the same publish, then parks the payload with the source topic, attempt count, and last error.

Broker.publish isolates per-handler exceptions: every subscriber in the snapshot runs, then the first error is rethrown (so DeadLetterFullError still surfaces after siblings have been called). Retry budget and parked uniqueness are keyed per subscription, not only by message.id, so two wrappers on one queue do not steal each other's retries or hide the last error.

Redrive publishes first and only then removes the envelope, so a failed replay leaves the poison payload in place. A full DLQ throws DeadLetterFullError instead of dropping evidence.

Closes #3.

Park a payload after it exhausts maxAttempts, isolate handler throws
so fan-out continues, and redrive only after a successful publish.
Publish finishes the subscriber snapshot before rethrowing the first
error so later handlers still run. Retry budget and parked envelopes
are keyed per wrapper, not only by message id.
@ThomasHartDev
ThomasHartDev merged commit c57796b into main Aug 16, 2026
1 check passed
@ThomasHartDev
ThomasHartDev deleted the thomas/feat/dead-letter branch August 16, 2026 06:19
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.

Dead-letter queue for poison messages

1 participant