You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AMQP使用topic exchange测试nack时报错TypeError问题咨询

排查RabbitMQ Topic Exchange中nack使用导致的错误

嘿,我来帮你搞定这两个RabbitMQ的错误,其实都是代码里的几个小细节没处理对:

第一个错误:AMPQ: TypeError: Cannot read property 'deliveryTag' of undefined

这个问题完全是因为你调用ch.nack()的姿势不对。RabbitMQ的nack方法要求第一个参数必须是收到的消息对象(也就是那个msg参数),但你现在传的是字符串'error occurred'——这显然不是一个消息对象,内部代码尝试读取它的deliveryTag属性时自然就会抛出“读取undefined属性”的错误。

第二个错误:UnhandledPromiseRejectionWarning

这个警告有两个触发原因:

  • 你把消费回调写成了async函数,在async函数里抛出同步错误(比如你写的throw 'error occurred')会被自动包装成一个被拒绝的Promise。虽然你写了try/catch,但还有另一个关键问题:
  • 你设置了{noAck: true},这意味着RabbitMQ会在消息推送给消费者后自动确认消息,这种情况下你再调用nack是完全无效的,甚至会引发额外的异步错误,因为消息已经被自动确认了,手动拒绝的操作已经没有意义,进而导致Promise状态异常。

修正后的完整代码

ch.bindQueue(q.queue, ex, 'key');
ch.consume(q.queue, async (msg) => {
    console.log(" Sub: [x] %s:'%s'", msg.fields.routingKey, msg.content.toString());
    const eventInfo = JSON.parse(msg.content.toString());
    try {
        throw 'error occurred';
    } catch(err) {
        console.error('处理消息时出错:', err);
        // 正确调用nack:第一个参数是消息对象,后面两个参数按需调整
        // 第二个参数allUpTo:是否拒绝所有未确认的消息,这里设为false
        // 第三个参数requeue:是否将当前消息重新放回队列,这里设为true(可根据需求改false)
        ch.nack(msg, false, true);
    }
}, {noAck: false}); // 必须设为false,才能手动执行nack/ack操作

关键修正点说明

  1. 关闭自动确认:把{noAck: true}改成{noAck: false},这样才能手动控制消息的确认或拒绝流程。
  2. 正确调用nack:第一个参数传入真正的消息对象msg,后面的两个参数可以根据你的业务需求调整是否批量拒绝、是否重新入队。
  3. 错误捕获完善:现在try/catch能正确捕获async函数内的错误,不会再出现未处理的Promise拒绝警告。

内容的提问来源于stack exchange,提问作者user269867

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:35:33