amqp-node / amqplib

AMQP 0-9-1 library and client for Node.JS

Home Page:https://amqp-node.github.io/amqplib/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow to throw errors on close event callback

nicosefer opened this issue · comments

Hi everyone!

We are using amqplib in a worker process and we need to exit the application with status code 1 when the rabbit connection gets closed.
The problem arise since we are trying to throw an error inside the close event callback to get catched by our process uncaughtException handler, but surprisingly the thrown error gets catched by the library instead and not re-throwed back to the application.
Of course we could call process.exit(1) directly from the close event handler a but it's not a clean solution.

Here's an example:

async function start() {
  const connection = await amqplib.connect(process.env.RABBITMQ_HOST);
  connection.on("close", () => {
    throw new Error("Uncaught error to be handled by the main application");
  });
}

process.on("uncaughtException", function (err) {
  console.error("uncaughtException", err);
  process.exit(1);
});

This is the catch statement that's preventing the Error to be uncaught:

  function go() {
    try {
      var f; while (f = self.recvFrame()) self.accept(f);
    }
    catch (e) {
      self.emit('frameError', e);
    }
  }

One solution that we found could be to check the error type and re-throw it if it's not considered a frameError kind of.

Hi @nicosefer,

The issue you are reporting is discussed here. It's definitely not easy to resolve, and the answer at the moment is to not throw synchronous errors from handlers. As an alternative you might consider something like the following

connection.on('close', (err) => {
  setImmediate(() => {
    process.emit('connection_lost', err);
  })
})

// Elsewhere
process.once('connection_lost', (err) => {
  if (err) console.error(err);
  process.exit(1);
});

Hi @cressie176 , thanks for your support!
We'd evaluated that alternative and surely we'll do it that way 👍