Summary
message.ack() and message.nack(false) are called without try/catch in multiple places. If the underlying channel is closed (broker restart, network partition), these synchronous calls throw — and the throw escapes into the unhandled-rejection path (see #20).
Where
src/core/message/RabbitMQMessage.ts:19-33 (the ack/nack wrappers)
src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor.ts:8-14 (bare message.ack() outside try/catch)
src/core/consumer/processors/RunMQFailedMessageRejecterProcessor.ts:8-15 (bare message.nack(false) inside the catch — escapes the catch)
Failure mode
- Consumer channel closes (broker restart, network partition).
- Handler completes, processor calls
message.ack() → throws → no catch → unhandled rejection.
- Or handler fails, rejecter calls
message.nack(false) → throws → escapes the catch → unhandled rejection.
Proposed fix
Wrap ack/nack in try/catch with a warn-level log. There is no useful recovery — the broker will redeliver after the channel closes anyway. Don't let plumbing errors blow up the consumer.
ack(): void {
if (!this.amqpMessage) return;
try { this.channel.ack(this.amqpMessage); }
catch (e) { /* logger.warn('ack failed (channel likely closed)', { cause: e }) */ }
}
(Logger needs to be threaded into RabbitMQMessage for the warn, or move the protection up into the processors.)
Acceptance criteria
Summary
message.ack()andmessage.nack(false)are called without try/catch in multiple places. If the underlying channel is closed (broker restart, network partition), these synchronous calls throw — and the throw escapes into the unhandled-rejection path (see #20).Where
src/core/message/RabbitMQMessage.ts:19-33(the ack/nack wrappers)src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor.ts:8-14(baremessage.ack()outside try/catch)src/core/consumer/processors/RunMQFailedMessageRejecterProcessor.ts:8-15(baremessage.nack(false)inside the catch — escapes the catch)Failure mode
message.ack()→ throws → no catch → unhandled rejection.message.nack(false)→ throws → escapes the catch → unhandled rejection.Proposed fix
Wrap ack/nack in try/catch with a warn-level log. There is no useful recovery — the broker will redeliver after the channel closes anyway. Don't let plumbing errors blow up the consumer.
(Logger needs to be threaded into
RabbitMQMessagefor the warn, or move the protection up into the processors.)Acceptance criteria