amqplib 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Change log for amqplib
2
2
 
3
+ ## v1.0.5
4
+ - Fix ConfirmChannel callbacks silently dropped on channel close when some publishes had no callback (fixes #191)
5
+
3
6
  ## v1.0.4
4
7
  - Updated build to use RabbitMQ 4.2
5
8
  - Fix memory leak in ConfirmChannel.publish when channel is already closed (fixes #842)
package/Makefile CHANGED
@@ -2,7 +2,7 @@ RABBITMQ_SRC_VERSION=v3.12.13
2
2
  JSON=amqp-rabbitmq-0.9.1.json
3
3
  AMQP_JSON=https://raw.githubusercontent.com/rabbitmq/rabbitmq-server/$(RABBITMQ_SRC_VERSION)/deps/rabbitmq_codegen/$(JSON)
4
4
 
5
- NODEJS_VERSIONS='18.1.0' '20.10.0' '22.14.0' '24.7.0'
5
+ NODEJS_VERSIONS='18.13.0' '20.10.0' '22.14.0' '24.7.0'
6
6
 
7
7
  UGLIFY=./node_modules/.bin/uglifyjs
8
8
 
package/lib/channel.js CHANGED
@@ -33,11 +33,12 @@ class Channel extends EventEmitter {
33
33
  }),
34
34
  );
35
35
  this.on('close', function () {
36
- let cb = this.unconfirmed.shift();
37
- while (cb) {
38
- if (cb) cb(new Error('channel closed'));
39
- cb = this.unconfirmed.shift();
36
+ const err = new Error('channel closed');
37
+ for (let i = 0; i < this.unconfirmed.length; i++) {
38
+ const cb = this.unconfirmed[i];
39
+ if (cb) cb(err);
40
40
  }
41
+ this.unconfirmed = this.unconfirmed.filter((cb) => cb === false);
41
42
  });
42
43
  // message frame state machine
43
44
  this.handleMessage = acceptDeliveryOrReturn;
@@ -236,11 +236,11 @@ class ConfirmChannel extends Channel {
236
236
  waitForConfirms() {
237
237
  const awaiting = [];
238
238
  const unconfirmed = this.unconfirmed;
239
- unconfirmed.forEach((val, index) => {
240
- if (val !== null) {
239
+ unconfirmed.forEach((cb, index) => {
240
+ if (cb !== null) {
241
241
  const confirmed = new Promise((resolve, reject) => {
242
242
  unconfirmed[index] = (err) => {
243
- if (val) val(err);
243
+ if (cb) cb(err);
244
244
  if (err === null) resolve();
245
245
  else reject(err);
246
246
  };
@@ -250,10 +250,10 @@ class ConfirmChannel extends Channel {
250
250
  });
251
251
  // Channel closed
252
252
  if (!this.pending) {
253
- let cb = this.unconfirmed.shift();
254
- while (cb) {
255
- if (cb) cb(new Error('channel closed'));
256
- cb = this.unconfirmed.shift();
253
+ const err = new Error('channel closed');
254
+ while (unconfirmed.length > 0) {
255
+ const cb = unconfirmed.shift();
256
+ if (cb) cb(err);
257
257
  }
258
258
  }
259
259
  return Promise.all(awaiting);
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "amqplib",
3
3
  "homepage": "http://amqp-node.github.io/amqplib/",
4
4
  "main": "./channel_api.js",
5
- "version": "1.0.4",
5
+ "version": "1.0.5",
6
6
  "description": "An AMQP 0-9-1 (e.g., RabbitMQ) library and client.",
7
7
  "repository": {
8
8
  "type": "git",
@@ -588,5 +588,25 @@ describe('Channel', () => {
588
588
  send(defs.BasicAck, { deliveryTag: 1, multiple: false }, ch);
589
589
  }, cb);
590
590
  }));
591
+
592
+ // Regression test for https://github.com/amqp-node/amqplib/issues/191
593
+ // pushConfirmCallback stores `false` for publishes with no callback.
594
+ // The close drain used `while (cb)` which stops at the first `false`,
595
+ // silently dropping all callbacks that follow it.
596
+ it('invokes all pending callbacks on close even when some publishes had no callback', channelTest((ch, cb) => {
597
+ let called = 0;
598
+ const countErr = (err) => { if (err) called++; };
599
+ ch.pushConfirmCallback(countErr); // tag = 1 — has callback
600
+ ch.pushConfirmCallback(null); // tag = 2 — no callback, stored as `false`
601
+ ch.pushConfirmCallback(countErr); // tag = 3 — has callback, dropped by while(cb) bug
602
+ open(ch).then(() => {
603
+ ch.toClosed('test close');
604
+ completes(() => {
605
+ assert.equal(2, called);
606
+ }, cb);
607
+ }, cb);
608
+ }, (_send, _wait, cb) => {
609
+ cb();
610
+ }));
591
611
  });
592
612
  });