@onlineapps/mq-client-core 1.0.7 → 1.0.10

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.7",
3
+ "version": "1.0.10",
4
4
  "description": "Core MQ client library for RabbitMQ - shared by infrastructure services and connectors",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -151,16 +151,26 @@ class RabbitMQClient extends EventEmitter {
151
151
  try {
152
152
  // Ensure queue exists if publishing directly to queue and using default exchange
153
153
  if (!exchange) {
154
- // For infrastructure queues, they should already exist with specific arguments
154
+ // CRITICAL: For infrastructure queues, they should already exist with specific arguments from queueConfig
155
155
  // Use queueChannel (regular channel) for checkQueue/assertQueue to avoid RPC reply queue issues
156
- // If queue doesn't exist (404), try to create it with default options
156
+ // If queue doesn't exist (404), we should NOT auto-create it - infrastructure queues must be created explicitly
157
+ // This prevents creating queues with wrong arguments (no TTL) which causes 406 errors later
157
158
  try {
158
159
  await this._queueChannel.checkQueue(queue);
159
160
  // Queue exists - proceed to publish
160
161
  } catch (checkErr) {
161
- // If queue doesn't exist (404), create it with default options
162
+ // If queue doesn't exist (404), this is an ERROR for infrastructure queues
163
+ // Infrastructure queues (workflow.*, registry.*) must be created explicitly with correct arguments
164
+ // We should NOT auto-create them here, as we don't have access to queueConfig in mq-client-core
162
165
  if (checkErr.code === 404) {
166
+ // Check if this is an infrastructure queue
167
+ const isInfraQueue = queue.startsWith('workflow.') || queue.startsWith('registry.');
168
+ if (isInfraQueue) {
169
+ throw new Error(`Cannot publish to infrastructure queue ${queue}: queue does not exist. Infrastructure queues must be created explicitly with correct arguments (TTL, max-length, etc.) before publishing.`);
170
+ }
171
+ // For non-infrastructure queues, allow auto-creation with default options
163
172
  const queueOptions = options.queueOptions || { durable: this._config.durable };
173
+ console.warn(`[RabbitMQClient] [mq-client-core] [PUBLISH] Auto-creating non-infrastructure queue ${queue} with default options (no TTL). This should be avoided for production.`);
164
174
  await this._queueChannel.assertQueue(queue, queueOptions);
165
175
  } else {
166
176
  // Other error - rethrow
@@ -252,8 +262,25 @@ class RabbitMQClient extends EventEmitter {
252
262
 
253
263
  console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Asserting queue ${queue} before consume() at ${new Date().toISOString()}`);
254
264
  console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Queue options:`, JSON.stringify(queueOptions, null, 2));
265
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] _queueChannel state: exists=${!!this._queueChannel}, closed=${this._queueChannel ? this._queueChannel.closed : 'N/A'}`);
255
266
 
267
+ // CRITICAL: Check if queue already exists with different arguments
268
+ // This can happen if sendToQueue() or amqplib's consume() auto-created it without TTL
256
269
  try {
270
+ const queueInfo = await this._queueChannel.checkQueue(queue);
271
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Queue ${queue} already exists with arguments:`, JSON.stringify(queueInfo.messageCount !== undefined ? { messageCount: queueInfo.messageCount, consumerCount: queueInfo.consumerCount } : queueInfo));
272
+ // If queue exists, we need to check if arguments match
273
+ // Note: checkQueue() doesn't return arguments, so we'll try assertQueue() and catch 406
274
+ } catch (checkErr) {
275
+ if (checkErr.code === 404) {
276
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Queue ${queue} does not exist (404), will be created with options`);
277
+ } else {
278
+ console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] checkQueue() failed for ${queue}:`, checkErr.message);
279
+ }
280
+ }
281
+
282
+ try {
283
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] About to call assertQueue(${queue}, ${JSON.stringify(queueOptions)})`);
257
284
  await this._queueChannel.assertQueue(queue, queueOptions);
258
285
  console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] ✓ Queue ${queue} asserted successfully`);
259
286
  } catch (assertErr) {
@@ -276,6 +303,26 @@ class RabbitMQClient extends EventEmitter {
276
303
  this._channel.prefetch(prefetch);
277
304
  }
278
305
 
306
+ // CRITICAL: Log before calling amqplib's consume()
307
+ // amqplib's consume() may internally call assertQueue() without parameters if queue doesn't exist
308
+ // This would create queue with default arguments (no TTL), causing 406 errors later
309
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] About to call amqplib's channel.consume(${queue})`);
310
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] ⚠ WARNING: amqplib's consume() may internally call assertQueue() WITHOUT parameters if queue doesn't exist`);
311
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] ⚠ WARNING: We already asserted queue with correct parameters above - this should prevent auto-creation`);
312
+
313
+ // CRITICAL: Wrap amqplib's channel.consume() to intercept any internal assertQueue() calls
314
+ // This will help us identify if amqplib is creating the queue without TTL
315
+ const originalConsume = this._channel.consume.bind(this._channel);
316
+ const originalAssertQueue = this._channel.assertQueue.bind(this._channel);
317
+
318
+ // Intercept assertQueue() calls to log them
319
+ this._channel.assertQueue = async function(queueName, options) {
320
+ console.log(`[RabbitMQClient] [mq-client-core] [INTERCEPT] assertQueue() called for: ${queueName}`);
321
+ console.log(`[RabbitMQClient] [mq-client-core] [INTERCEPT] Options:`, JSON.stringify(options || {}, null, 2));
322
+ console.log(`[RabbitMQClient] [mq-client-core] [INTERCEPT] Stack trace:`, new Error().stack.split('\n').slice(1, 10).join('\n'));
323
+ return originalAssertQueue.call(this, queueName, options);
324
+ };
325
+
279
326
  await this._channel.consume(
280
327
  queue,
281
328
  async (msg) => {