skip to Main Content

I’m new to Node.js and I’m trying to code two nested try/catch and put retry logic for it. So when inner try/catch catches error I want it to send to outer catch and inside of it I will increase retry count by 1. So when it comes to 5 I will return from while loop. But my problem is that when inner try/catch throws an exception it is not caught by outer one. How can I make sure that it catches the error?

    try {
      channel.assertQueue(name, { durable: true, arguments: { "x-queue-type": "quorum" } }, async (error, queue) => {
        if (error)
          throw error;

        if (queue) {
          try {
            channel.sendToQueue(name, Buffer.from(message));
          } catch (e) {
            console.log(e);
            throw e;
          }
        }
      });
    } catch (e) {
      //retry count will be increased.
      throw e.message;
    }

2

Answers


  1. To ensure that the outer catch block catches the error thrown in the inner try/catch block, you can modify your code as follows:

    let retryCount = 0;
    
    async function attemptToSendMessage() {
      while (retryCount < 5) {
        try {
          await new Promise((resolve, reject) => {
            channel.assertQueue(
              name,
              { durable: true, arguments: { "x-queue-type": "quorum" } },
              async (error, queue) => {
                if (error) {
                  reject(error); // Reject the promise if an error occurs
                  return;
                }
    
                if (queue) {
                  try {
                    channel.sendToQueue(name, Buffer.from(message));
                    resolve(); // Resolve the promise if the message is sent successfully
                  } catch (e) {
                    reject(e); // Reject the promise if an error occurs while sending the message
                  }
                }
              }
            );
          });
          break; // Exit the while loop if the message is sent successfully
        } catch (e) {
          console.log(e);
          retryCount++; // Increase the retry count
        }
      }
    
      if (retryCount === 5) {
        throw new Error("Failed to send message after 5 attempts.");
      }
    }
    
    // Usage
    try {
      await attemptToSendMessage();
    } catch (e) {
      // Handle the error here
      console.log(e.message);
    }
    
    Login or Signup to reply.
  2. You shouldn’t pass a callback to channel.assertQueue, and not an async one for certain, instead you should promisify it. With await, you can then catch the errors in the outer try/catch.

    You’re probably looking for

    async function attemptToSendMessage() {
      for (let retryCount = 0; retryCount < 5; retryCount++) {
        try {
          const queue = await new Promise((resolve, reject) => {
            channel.assertQueue(
              name,
              { durable: true, arguments: { "x-queue-type": "quorum" } },
              (error, queue) => {
                if (error) reject(error);
                else resolve(queue);
              }
            );
          });
          if (queue) {
            await channel.sendToQueue(name, Buffer.from(message));
          }
          return; // Exit the loop if the message is sent successfully
        } catch (e) {
          console.error(e);
        }
      }
      throw new Error("Failed to send message after 5 attempts.");
    }
    

    However, assuming you are using this API, you don’t even need to promisify the assertQueue function yourself – it already returns a promise if you don’t pass a callback. So simplify further to

    async function attemptToSendMessage() {
      for (let retryCount = 0; retryCount < 5; retryCount++) {
        try {
          const queue = await channel.assertQueue(
            name,
            { durable: true, arguments: { "x-queue-type": "quorum" } },
          );
          if (queue) {
            await channel.sendToQueue(name, Buffer.from(message));
          }
          return; // Exit the loop if the message is sent successfully
        } catch (e) {
          console.error(e);
        }
      }
      throw new Error("Failed to send message after 5 attempts.");
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search