@onlineapps/mq-client-core 1.0.27 → 1.0.28

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/mq-client-core",
3
- "version": "1.0.27",
3
+ "version": "1.0.28",
4
4
  "description": "Core MQ client library for RabbitMQ - shared by infrastructure services and connectors",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -164,8 +164,9 @@ class RabbitMQClient extends EventEmitter {
164
164
  * @throws {Error} If publish fails or channel is not available.
165
165
  */
166
166
  async publish(queue, buffer, options = {}) {
167
- if (!this._channel) {
168
- throw new Error('Cannot publish: channel is not initialized');
167
+ // Check channel state before publish
168
+ if (!this._channel || this._channel.closed) {
169
+ throw new Error('Cannot publish: channel is not initialized or closed');
169
170
  }
170
171
 
171
172
  const exchange = this._config.exchange || '';
@@ -181,6 +182,21 @@ class RabbitMQClient extends EventEmitter {
181
182
  // If queue doesn't exist (404), we should NOT auto-create it - infrastructure queues must be created explicitly
182
183
  // This prevents creating queues with wrong arguments (no TTL) which causes 406 errors later
183
184
  try {
185
+ // Check queueChannel state
186
+ if (!this._queueChannel || this._queueChannel.closed) {
187
+ // Recreate queueChannel if closed
188
+ if (this._connection && !this._connection.closed) {
189
+ this._queueChannel = await this._connection.createChannel();
190
+ this._queueChannel.on('error', (err) => {
191
+ console.warn('[RabbitMQClient] Queue channel error:', err.message);
192
+ });
193
+ this._queueChannel.on('close', () => {
194
+ console.warn('[RabbitMQClient] Queue channel closed');
195
+ });
196
+ } else {
197
+ throw new Error('Cannot publish: connection is closed');
198
+ }
199
+ }
184
200
  await this._queueChannel.checkQueue(queue);
185
201
  // Queue exists - proceed to publish
186
202
  } catch (checkErr) {
@@ -215,15 +231,31 @@ class RabbitMQClient extends EventEmitter {
215
231
  }
216
232
  }
217
233
  // Publish to queue using ConfirmChannel (for publisher confirms)
234
+ // Check channel state again before sendToQueue
235
+ if (this._channel.closed) {
236
+ throw new Error('Cannot publish: channel closed during operation');
237
+ }
218
238
  this._channel.sendToQueue(queue, buffer, { persistent, headers });
219
239
  } else {
220
240
  // If exchange is specified, assert exchange and publish to it
241
+ if (this._channel.closed) {
242
+ throw new Error('Cannot publish: channel closed during operation');
243
+ }
221
244
  await this._channel.assertExchange(exchange, 'direct', { durable: this._config.durable });
222
245
  this._channel.publish(exchange, routingKey, buffer, { persistent, headers });
223
246
  }
224
- // Wait for confirmation
225
- await this._channel.waitForConfirms();
247
+ // Wait for confirmation (with timeout to prevent hanging)
248
+ const confirmPromise = this._channel.waitForConfirms();
249
+ const timeoutPromise = new Promise((_, reject) => {
250
+ setTimeout(() => reject(new Error('Publisher confirm timeout after 5 seconds')), 5000);
251
+ });
252
+ await Promise.race([confirmPromise, timeoutPromise]);
226
253
  } catch (err) {
254
+ // If channel was closed, mark it for recreation
255
+ if (err.message && (err.message.includes('Channel closed') || err.message.includes('channel is closed') || this._channel?.closed)) {
256
+ console.warn('[RabbitMQClient] [mq-client-core] [PUBLISH] Channel closed during publish, will need to reconnect');
257
+ this._channel = null;
258
+ }
227
259
  this.emit('error', err);
228
260
  throw err;
229
261
  }
@@ -261,8 +293,10 @@ class RabbitMQClient extends EventEmitter {
261
293
  console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] Cannot load queueConfig from @onlineapps/conn-infra-mq:`, requireErr.message);
262
294
  console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] Using default queue options (this may cause 406 errors if queue exists with different args)`);
263
295
  }
264
- const isInfraQueue = queueConfig.isInfrastructureQueue(queue);
265
- const isBusinessQueue = queueConfig.isBusinessQueue(queue);
296
+
297
+ // Only check queue types if queueConfig is available
298
+ const isInfraQueue = queueConfig ? queueConfig.isInfrastructureQueue(queue) : false;
299
+ const isBusinessQueue = queueConfig ? queueConfig.isBusinessQueue(queue) : false;
266
300
 
267
301
  let queueOptions = options.queueOptions || { durable };
268
302