Problem
Without recover(), a panic in a message-processing goroutine crashes it silently. The message is never acknowledged, RabbitMQ redelivers it, and the same panic fires again — infinite loop for poison messages.
Fix: recover() + Dead Letter Queue
go func(msg amqp.Delivery) {
defer func() {
if r := recover(); r != nil {
logger.Error("panic in message processing",
zap.Any("panic", r),
zap.String("stack", string(debug.Stack())))
c.sendToDLQ(msg)
msg.Ack(false) // remove from main queue
}
}()
// process message...
}(msg)Why DLQ, not Nack?
| Action | Result |
|---|---|
Nack(requeue=false) | Message lost forever |
Nack(requeue=true) | Infinite loop for poison messages |
Send to DLQ + Ack | Quarantined for debugging, main queue unblocked |
DLQ lets you inspect the failing message without blocking healthy ones.
See also
- parallel-polling-per-entity — publisher side: how messages are produced
- context-independent-cleanup — cleanup after panic must not use a cancelled context