Dead Letter Queue
When a handler fails after all retries are exhausted, the failed message can be stored in a dead letter queue (DLQ) for later inspection and replay.
Enabling the DLQ
Set deadLetterQueue: true in the configuration:
const synkro = await Synkro.start({ transport: "redis", connectionUrl: "redis://localhost:6379", deadLetterQueue: true,});How it works
- A handler throws an error.
- Synkro retries according to the
RetryConfig. - After all retries are exhausted, the message is published as failed.
- If
deadLetterQueueis enabled, aDeadLetterItemis pushed to the DLQ.
Inspecting failed messages
Retrieve DLQ items for a specific event type:
const items = await synkro.getDeadLetterItems("payment:charge");
for (const item of items) { console.log(`Failed at: ${item.failedAt}`); console.log(`Attempts: ${item.attempts}`); console.log(`Errors:`, item.errors); console.log(`Payload:`, item.payload);}You can limit the number of items returned:
const items = await synkro.getDeadLetterItems("payment:charge", { limit: 10 });Replaying failed messages
Reprocess a failed message by passing it back through publish:
const items = await synkro.getDeadLetterItems("payment:charge");
for (const item of items) { await synkro.replayDeadLetterItem(item);}replayDeadLetterItem re-publishes the event with the original eventType, payload, and requestId.
Clearing the DLQ
Remove all items from a specific event’s DLQ:
await synkro.clearDeadLetterQueue("payment:charge");DeadLetterItem type
type DeadLetterItem = { eventType: string; requestId: string; payload: unknown; errors: Array<{ message: string; name?: string }>; failedAt: string; // ISO 8601 timestamp attempts: number; // total attempts (initial + retries)};