@onlineapps/conn-infra-mq 1.1.41 → 1.1.43

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/conn-infra-mq",
3
- "version": "1.1.41",
3
+ "version": "1.1.43",
4
4
  "description": "A promise-based, broker-agnostic client for sending and receiving messages via RabbitMQ",
5
5
  "main": "src/index.js",
6
6
  "repository": {
@@ -114,6 +114,40 @@ class RabbitMQClient extends EventEmitter {
114
114
  }
115
115
  }
116
116
 
117
+ /**
118
+ * Recreates the publish channel if it's closed.
119
+ * Used when channel closes unexpectedly (e.g., due to 406 errors).
120
+ * @private
121
+ * @returns {Promise<void>}
122
+ * @throws {Error} If connection is not available or channel recreation fails.
123
+ */
124
+ async _recreateChannel() {
125
+ if (!this._connection) {
126
+ throw new Error('Cannot recreate channel: connection is not available');
127
+ }
128
+
129
+ try {
130
+ // Close old channel if it exists
131
+ if (this._channel) {
132
+ try {
133
+ await this._channel.close();
134
+ } catch (err) {
135
+ // Ignore errors when closing already-closed channel
136
+ }
137
+ }
138
+
139
+ // Create new ConfirmChannel
140
+ this._channel = await this._connection.createConfirmChannel();
141
+ this._channel.on('error', (err) => this.emit('error', err));
142
+ this._channel.on('close', () => {
143
+ this.emit('error', new Error('RabbitMQ channel closed unexpectedly'));
144
+ });
145
+ } catch (err) {
146
+ this._channel = null;
147
+ throw new Error(`Failed to recreate channel: ${err.message}`);
148
+ }
149
+ }
150
+
117
151
  /**
118
152
  * Disconnects: closes channel and connection.
119
153
  * @returns {Promise<void>}
@@ -158,6 +192,16 @@ class RabbitMQClient extends EventEmitter {
158
192
  if (!this._channel) {
159
193
  throw new Error('Cannot publish: channel is not initialized');
160
194
  }
195
+
196
+ // Check if channel is closed and recreate if needed
197
+ if (this._channel.closed) {
198
+ console.warn('[RabbitMQClient] Publish channel is closed, recreating...');
199
+ try {
200
+ await this._recreateChannel();
201
+ } catch (recreateErr) {
202
+ throw new Error(`Cannot publish: channel is closed and recreation failed: ${recreateErr.message}`);
203
+ }
204
+ }
161
205
 
162
206
  const exchange = this._config.exchange || '';
163
207
  const routingKey = options.routingKey || queue;
@@ -177,20 +221,11 @@ class RabbitMQClient extends EventEmitter {
177
221
  // Business queue - should already exist, skip checkQueue() to avoid channel closure
178
222
  console.log(`[RabbitMQClient] DEBUG: Business queue ${queue}, skipping checkQueue() in publish() - queue should already exist`);
179
223
  } else {
180
- // Infrastructure queue - check if it exists
181
- const queueOptions = this._getQueueOptions(queue);
182
- try {
183
- await this._queueChannel.checkQueue(queue);
184
- // Queue exists - proceed to publish
185
- } catch (checkErr) {
186
- // If queue doesn't exist (404), create it
187
- if (checkErr.code === 404) {
188
- await this._queueChannel.assertQueue(queue, queueOptions);
189
- } else {
190
- // Other error (including 406) - queue exists with different args, proceed
191
- console.warn(`[RabbitMQClient] Queue ${queue} exists with different arguments, using as-is`);
192
- }
193
- }
224
+ // Infrastructure queue - skip assertQueue() to avoid 406 channel closure
225
+ // Infrastructure queues are created by monitoring consumer at startup
226
+ // If queue doesn't exist, publish() will fail with a clear error
227
+ // This matches the pattern used for business queues - early creation, no runtime checks
228
+ console.log(`[RabbitMQClient] DEBUG: Infrastructure queue ${queue}, skipping assertQueue() - queue should already exist (created by monitoring consumer)`);
194
229
  }
195
230
  // Publish using ConfirmChannel (for publisher confirms)
196
231
  this._channel.sendToQueue(queue, buffer, { persistent, headers, routingKey });