0

Hey Guys, I am running a discordbot with Discord.js in Node.js. My goal is to run it via pm2 on a Linux Ubuntu Server.

I want to build a cleanup process before exiting the program on uncaught Exception.

However when I throw a sample error and run it via pm2 uncaught Exception is not reached, pm2 is just logging the error and continue running the script. When running it directly with Node.js, without pm2 everything works as expected.

Here is my code:

process.on('uncaughtException', async (err, origin) => {
    console.log('test')
    // await Cleanup();
    process.exit(1);
});

Here the console output running it with pm2:

Error: Test error
at Object.execute (script xxxx)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async xxx

As you can see pm2 is kind of preventing the Test error to reach uncaughtException. Pm2 is not restarting the script, and is not logging 'test'

I also tried catching the error via SIGINT or SIGTERM but none of these are working.

Is there an option in pm2 to disable this behavior?

Thanks for any help!

JustAG33K
  • 1,403
  • 3
  • 13
  • 28
Huetti
  • 1
  • 3

2 Answers2

0

PM2 automatically restart applications when they crashed or terminate.

As i remember, you can not disable this: https://pm2.keymetrics.io/docs/usage/restart-strategies/

UPDATE

Normally process.exit(0); will restart the pm2 process.

You also have a workaround to force restart from within your app. You need to start your app with the --watch parameter:

pm2 start app.js --watch

Thus, you just need to write/modify/delete a temp file in a directory inside your application directory. When pm2 detect new file it will restart your app. It's not a clean solution, but this work.

Alaindeseine
  • 3,260
  • 1
  • 11
  • 21
  • Thank your for your answer. Unfortunately, pm2 does not restart the script at all it keeps running. Your answer is my goal, I want pm2 to restart the script and not to disable that auto restart. – Huetti Aug 07 '22 at 18:12
  • @Huetti Ok, i have not understand your need of restarting the app. I have updated my answer. – Alaindeseine Aug 07 '22 at 19:23
  • Thank you, this seems promising, I will try it tomorrow. – Huetti Aug 07 '22 at 19:51
  • It is a solution for errors you can predict, but I can't cover all my statements in try catch, when I am not sure if they will never throw an unexpected error. Sometimes, when for example the db connection throws an error or a sql statement I want a restart. – Huetti Aug 09 '22 at 07:07
  • I'm not shure that restarting on each errors is a good pattern. If you restart on an sql error statement or whatever instead of dealing with it (logging, e-mail alerts, or everything else) you will stop all the others user request that are on the execution loop. – Alaindeseine Aug 09 '22 at 07:43
0

The function in which the error is thrown is async. That led me to the docs of the unhandledRejection event.

In addition to uncaughtException I added unhandledRejection:

process.on('uncaughtException', async (err, origin) => {
  await Cleanup(...); //my own cleanup
  process.exit(0);
});

process.on('unhandledRejection', async (reason, promise) => {
  await Cleanup(...); //my own cleanup
  process.exit(0);
});

Now pm2 is restarting after a cleanup whenever an uncaught Error/Exception is thrown.

Huetti
  • 1
  • 3