@onlineapps/conn-infra-mq 1.1.43 → 1.1.45

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.43",
3
+ "version": "1.1.45",
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": {
@@ -365,24 +365,44 @@ class QueueManager {
365
365
  }
366
366
  }
367
367
 
368
- // CRITICAL: Use assertQueue() DIRECTLY - it's idempotent and safer than checkQueue() + assertQueue()
369
- // assertQueue() creates queue if it doesn't exist, or does nothing if it exists with same params
370
- // If queue exists with different params (406), channel closes but that's OK - we accept the queue
371
- let queueCreated = false;
368
+ // CRITICAL: Ensure channel is usable before assertQueue
369
+ // Recreate if closed (may have been closed by previous operations)
370
+ if (!channel || channel.closed) {
371
+ console.log(`[QueueManager] DEBUG: Channel is closed before assertQueue ${queueName}, recreating...`);
372
+ channel = await transport._connection.createChannel();
373
+ channel._createdAt = new Date().toISOString();
374
+ channel._closeReason = null;
375
+ channel._lastOperation = `Recreated before assertQueue ${queueName}`;
376
+
377
+ channel.on('error', (err) => {
378
+ console.error('[RabbitMQClient] Recreated queue channel error:', err.message);
379
+ channel._closeReason = `Error: ${err.message} (code: ${err.code})`;
380
+ });
381
+ channel.on('close', () => {
382
+ console.error('[RabbitMQClient] Recreated queue channel closed');
383
+ console.error('[RabbitMQClient] Close reason:', channel._closeReason || 'Unknown');
384
+ });
385
+
386
+ transport._queueChannel = channel;
387
+ console.log(`[QueueManager] DEBUG: Channel recreated before assertQueue ${queueName}`);
388
+ }
372
389
 
373
390
  // Track operation on channel for debugging
374
391
  if (channel && channel._lastOperation !== undefined) {
375
392
  channel._lastOperation = `About to assertQueue ${queueName}`;
376
393
  }
377
394
 
395
+ let queueCreated = false;
396
+
378
397
  try {
379
- console.log(`[QueueManager] DEBUG: About to assertQueue ${queueName} directly (idempotent)`);
398
+ console.log(`[QueueManager] DEBUG: About to assertQueue ${queueName} with correct arguments`);
380
399
  console.log(`[QueueManager] DEBUG: Channel state: exists=${!!channel}, closed=${channel ? (channel.closed === true ? 'true' : channel.closed === false ? 'false' : 'undefined') : 'N/A'}`);
400
+ console.log(`[QueueManager] DEBUG: Queue options:`, JSON.stringify(queueOptions));
381
401
 
382
402
  // CRITICAL: Use assertQueue() DIRECTLY - it's idempotent
383
403
  // If queue doesn't exist → creates it
384
404
  // If queue exists with same params → does nothing (OK)
385
- // If queue exists with different params → 406, channel closes (but we accept the queue)
405
+ // If queue exists with different params → 406, channel closes (should not happen now, but handle it)
386
406
  await channel.assertQueue(queueName, queueOptions);
387
407
 
388
408
  // Queue created or already exists with same params
@@ -397,37 +417,59 @@ class QueueManager {
397
417
  console.log(`[QueueManager] DEBUG: assertQueue failed for ${queueName}:`, assertErr.message);
398
418
  console.log(`[QueueManager] DEBUG: Error code: ${assertErr.code}`);
399
419
 
400
- // If 406 PRECONDITION-FAILED, queue exists with different args - accept it
401
- // Channel is closed by server, but that's OK - queue exists and we can use it
420
+ // If 406 PRECONDITION-FAILED, queue exists with different args
421
+ // Delete it and recreate with correct args
402
422
  if (assertErr.code === 406) {
403
- console.warn(`[QueueManager] Queue ${queueName} exists with different arguments (406), accepting as-is:`, assertErr.message);
404
- queues[queueInfo.type] = queueName;
405
- queueCreated = true;
406
- console.info(`[QueueManager] ✓ Business queue exists (different args, accepted): ${queueName}`);
423
+ console.warn(`[QueueManager] Queue ${queueName} exists with different arguments (406), deleting and recreating...`);
424
+ console.warn(`[QueueManager] Expected args:`, JSON.stringify(queueOptions.arguments));
407
425
 
408
- // Channel is closed, but we need to recreate it for next queue
409
- // Don't throw error - queue exists, we just need new channel
426
+ // Delete queue and recreate with correct args
410
427
  try {
411
- const newChannel = await transport._connection.createChannel();
412
- newChannel._createdAt = new Date().toISOString();
413
- newChannel._closeReason = null;
414
- newChannel._lastOperation = `Recreated after 406 for ${queueName}`;
428
+ // Recreate channel (closed by 406)
429
+ channel = await transport._connection.createChannel();
430
+ channel._createdAt = new Date().toISOString();
431
+ channel._closeReason = null;
432
+ channel._lastOperation = `Recreated after 406 for ${queueName}`;
415
433
 
416
- newChannel.on('error', (err) => {
434
+ channel.on('error', (err) => {
417
435
  console.error('[RabbitMQClient] Recreated queue channel error:', err.message);
418
- newChannel._closeReason = `Error: ${err.message} (code: ${err.code})`;
436
+ channel._closeReason = `Error: ${err.message} (code: ${err.code})`;
419
437
  });
420
- newChannel.on('close', () => {
438
+ channel.on('close', () => {
421
439
  console.error('[RabbitMQClient] Recreated queue channel closed');
422
- console.error('[RabbitMQClient] Close reason:', newChannel._closeReason || 'Unknown');
440
+ console.error('[RabbitMQClient] Close reason:', channel._closeReason || 'Unknown');
423
441
  });
424
442
 
425
- channel = newChannel;
426
443
  transport._queueChannel = channel;
427
- console.log(`[QueueManager] DEBUG: Channel recreated after 406 for ${queueName}`);
428
- } catch (recreateErr) {
429
- // Even if channel recreation fails, queue exists - log warning but continue
430
- console.warn(`[QueueManager] Failed to recreate channel after 406 for ${queueName}, but queue exists:`, recreateErr.message);
444
+
445
+ // Delete queue
446
+ await channel.deleteQueue(queueName);
447
+ console.log(`[QueueManager] Deleted queue ${queueName} after 406 error`);
448
+
449
+ // Recreate channel again (deleteQueue may close it)
450
+ channel = await transport._connection.createChannel();
451
+ channel._createdAt = new Date().toISOString();
452
+ channel._closeReason = null;
453
+ channel._lastOperation = `Recreated after deleteQueue ${queueName}`;
454
+
455
+ channel.on('error', (err) => {
456
+ console.error('[RabbitMQClient] Recreated queue channel error:', err.message);
457
+ channel._closeReason = `Error: ${err.message} (code: ${err.code})`;
458
+ });
459
+ channel.on('close', () => {
460
+ console.error('[RabbitMQClient] Recreated queue channel closed');
461
+ console.error('[RabbitMQClient] Close reason:', channel._closeReason || 'Unknown');
462
+ });
463
+
464
+ transport._queueChannel = channel;
465
+
466
+ // Try assertQueue again
467
+ await channel.assertQueue(queueName, queueOptions);
468
+ console.log(`[QueueManager] ✓ Recreated queue ${queueName} with correct arguments`);
469
+ queues[queueInfo.type] = queueName;
470
+ queueCreated = true;
471
+ } catch (retryErr) {
472
+ throw new Error(`Failed to recreate queue ${queueName} after 406 error: ${retryErr.message}`);
431
473
  }
432
474
  } else {
433
475
  // Other error - critical, cannot continue