@onlineapps/mq-client-core 1.0.6 → 1.0.8

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.6",
3
+ "version": "1.0.8",
4
4
  "description": "Core MQ client library for RabbitMQ - shared by infrastructure services and connectors",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/BaseClient.js CHANGED
@@ -146,7 +146,14 @@ class BaseClient {
146
146
  if (typeof noAck === 'boolean') consumeOptions.noAck = noAck;
147
147
  if (options.queueOptions) consumeOptions.queueOptions = options.queueOptions;
148
148
 
149
+ // CRITICAL: Log all consume() calls for transparency
150
+ console.log(`[BaseClient] [CONSUMER] Starting consume() for queue: ${queue} at ${new Date().toISOString()}`);
151
+ console.log(`[BaseClient] [CONSUMER] Options:`, JSON.stringify(consumeOptions, null, 2));
152
+ console.log(`[BaseClient] [CONSUMER] Transport type: ${this._transport?.constructor?.name || 'unknown'}`);
153
+ console.log(`[BaseClient] [CONSUMER] Connected: ${this._connected}`);
154
+
149
155
  try {
156
+ const consumeStartTime = Date.now();
150
157
  await this._transport.consume(
151
158
  queue,
152
159
  async (msg) => {
@@ -162,7 +169,10 @@ class BaseClient {
162
169
  },
163
170
  consumeOptions
164
171
  );
172
+ const consumeEndTime = Date.now();
173
+ console.log(`[BaseClient] [CONSUMER] ✓ consume() completed for queue: ${queue} (took ${consumeEndTime - consumeStartTime}ms)`);
165
174
  } catch (err) {
175
+ console.error(`[BaseClient] [CONSUMER] ✗ consume() failed for queue: ${queue}`, err.message);
166
176
  throw new ConsumeError(`Failed to start consumer for queue "${queue}"`, queue, err);
167
177
  }
168
178
  }
@@ -203,29 +203,103 @@ class RabbitMQClient extends EventEmitter {
203
203
  // Skip assertQueue for reply queues (they're already created with specific settings)
204
204
  // Reply queues start with 'rpc.reply.' and are created as non-durable
205
205
  if (!queue.startsWith('rpc.reply.')) {
206
- // Use queueChannel (regular channel) for queue operations to avoid RPC reply queue issues
207
- // Simple queue assertion - infrastructure services should ensure queues exist
208
- // If queue doesn't exist, assertQueue will create it with default options
209
- // If it exists with different args (406), log warning and proceed
210
- const queueOptions = options.queueOptions || { durable };
211
- try {
212
- await this._queueChannel.assertQueue(queue, queueOptions);
213
- } catch (assertErr) {
214
- // If queue exists with different arguments (406), use it as-is
215
- if (assertErr.code === 406) {
216
- console.warn(`[RabbitMQClient] Queue ${queue} exists with different arguments, using as-is:`, assertErr.message);
217
- // Don't try to re-assert - just proceed to consume
218
- } else {
219
- // Other error - rethrow
220
- throw assertErr;
206
+ // CRITICAL: Use queueConfig.js to get correct parameters (TTL, max-length, etc.)
207
+ // This prevents 406 PRECONDITION-FAILED errors from TTL mismatches
208
+ // Note: mq-client-core is for infrastructure services, but we need queueConfig from conn-infra-mq
209
+ // Try to load it - if it fails, we'll use defaults
210
+ let queueConfig = null;
211
+ try {
212
+ queueConfig = require('@onlineapps/conn-infra-mq/src/config/queueConfig');
213
+ } catch (requireErr) {
214
+ console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] Cannot load queueConfig from @onlineapps/conn-infra-mq:`, requireErr.message);
215
+ console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] Using default queue options (this may cause 406 errors if queue exists with different args)`);
216
+ }
217
+ const isInfraQueue = queueConfig.isInfrastructureQueue(queue);
218
+ const isBusinessQueue = queueConfig.isBusinessQueue(queue);
219
+
220
+ let queueOptions = options.queueOptions || { durable };
221
+
222
+ if (queueConfig) {
223
+ if (isInfraQueue) {
224
+ // Infrastructure queue - use central config
225
+ try {
226
+ const infraConfig = queueConfig.getInfrastructureQueueConfig(queue);
227
+ queueOptions = {
228
+ durable: infraConfig.durable !== false,
229
+ arguments: { ...infraConfig.arguments }
230
+ };
231
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Asserting infrastructure queue ${queue} with config from queueConfig`);
232
+ } catch (configErr) {
233
+ console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] Infrastructure queue config not found for ${queue}, using default:`, configErr.message);
234
+ }
235
+ } else if (isBusinessQueue) {
236
+ // Business queue - use central config
237
+ try {
238
+ const parsed = queueConfig.parseBusinessQueue(queue);
239
+ if (parsed) {
240
+ const businessConfig = queueConfig.getBusinessQueueConfig(parsed.queueType, parsed.serviceName);
241
+ queueOptions = {
242
+ durable: businessConfig.durable !== false,
243
+ arguments: { ...businessConfig.arguments }
244
+ };
245
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Asserting business queue ${queue} with config from queueConfig`);
246
+ }
247
+ } catch (configErr) {
248
+ console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] Business queue config not found for ${queue}, using default:`, configErr.message);
221
249
  }
222
250
  }
223
251
  }
252
+
253
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Asserting queue ${queue} before consume() at ${new Date().toISOString()}`);
254
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Queue options:`, JSON.stringify(queueOptions, null, 2));
255
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] _queueChannel state: exists=${!!this._queueChannel}, closed=${this._queueChannel ? this._queueChannel.closed : 'N/A'}`);
256
+
257
+ // CRITICAL: Check if queue already exists with different arguments
258
+ // This can happen if sendToQueue() or amqplib's consume() auto-created it without TTL
259
+ try {
260
+ const queueInfo = await this._queueChannel.checkQueue(queue);
261
+ 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));
262
+ // If queue exists, we need to check if arguments match
263
+ // Note: checkQueue() doesn't return arguments, so we'll try assertQueue() and catch 406
264
+ } catch (checkErr) {
265
+ if (checkErr.code === 404) {
266
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] Queue ${queue} does not exist (404), will be created with options`);
267
+ } else {
268
+ console.warn(`[RabbitMQClient] [mq-client-core] [CONSUMER] checkQueue() failed for ${queue}:`, checkErr.message);
269
+ }
270
+ }
271
+
272
+ try {
273
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] About to call assertQueue(${queue}, ${JSON.stringify(queueOptions)})`);
274
+ await this._queueChannel.assertQueue(queue, queueOptions);
275
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] ✓ Queue ${queue} asserted successfully`);
276
+ } catch (assertErr) {
277
+ // If queue exists with different arguments (406), this is a CRITICAL ERROR
278
+ // We should NOT proceed - the root cause must be fixed
279
+ if (assertErr.code === 406) {
280
+ console.error(`[RabbitMQClient] [mq-client-core] [CONSUMER] ✗ CRITICAL: Queue ${queue} exists with different arguments!`);
281
+ console.error(`[RabbitMQClient] [mq-client-core] [CONSUMER] Error:`, assertErr.message);
282
+ console.error(`[RabbitMQClient] [mq-client-core] [CONSUMER] Expected options:`, JSON.stringify(queueOptions, null, 2));
283
+ console.error(`[RabbitMQClient] [mq-client-core] [CONSUMER] This means assertQueue() was called without parameters somewhere else. Root cause must be fixed!`);
284
+ throw new Error(`Cannot assertQueue ${queue}: queue exists with different arguments. Root cause: assertQueue() was called without parameters. Fix the root cause instead of proceeding.`);
285
+ } else {
286
+ // Other error - rethrow
287
+ throw assertErr;
288
+ }
289
+ }
290
+ }
224
291
  // Set prefetch if provided
225
292
  if (typeof prefetch === 'number') {
226
293
  this._channel.prefetch(prefetch);
227
294
  }
228
295
 
296
+ // CRITICAL: Log before calling amqplib's consume()
297
+ // amqplib's consume() may internally call assertQueue() without parameters if queue doesn't exist
298
+ // This would create queue with default arguments (no TTL), causing 406 errors later
299
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] About to call amqplib's channel.consume(${queue})`);
300
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] ⚠ WARNING: amqplib's consume() may internally call assertQueue() WITHOUT parameters if queue doesn't exist`);
301
+ console.log(`[RabbitMQClient] [mq-client-core] [CONSUMER] ⚠ WARNING: We already asserted queue with correct parameters above - this should prevent auto-creation`);
302
+
229
303
  await this._channel.consume(
230
304
  queue,
231
305
  async (msg) => {