breejs / bree

Bree is a Node.js and JavaScript job task scheduler with worker threads, cron, Date, and human syntax. Built for @ladjs, @forwardemail, @spamscanner, @cabinjs.
https://jobscheduler.net
MIT License
3.02k stars 78 forks source link

Throwing error inside Async IIFE function (Using Node 14) not actually throwing error and did not terminate the worker #110

Closed spyndutz closed 3 years ago

spyndutz commented 3 years ago

Hello there, I'm currently using Node v14.16.0

Using the example here I've written my own job script.

Let's say we throw an error inside the Async IIFE like this: jobs/example.js

(async () => {
  await doSomeAwaitFunction();
  throw new Error('Intentionally throws error');
})().catch((err) => { throw err; });

the code above will result in the process printing to console these warning:

UnhandledPromiseRejectionWarning: Intentionally throw errors
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code

I know this shouldn't be Bree specific, it is more likely to be how NodeJS currently handle UnhandledPromiseRejection error which only prints error logs and doesn't actually terminate the node process (Which make the worker just hanging there as stale jobs).

The expected behavior is to terminate the process and send the thrown errors back to the Bree, and thus invoking my own custom errorHandler function that I have defined (Currently the errorHandler doesn't get invoked when the above behavior happens).

Is there any way to make the worker use the --unhandled-rejections=strict without actually using it in our main application? Or is there any workaround to address this issue?

spyndutz commented 3 years ago

Found a workaround by adding unhandledRejection process listener for every jobs

process.on('unhandledRejection', (err) => {
  throw err;
});
shadowgate15 commented 3 years ago

This is likely due to some module that has been imported within the script throwing an unhandled rejection. This won't be caught by .catch() chain. Check out this, which suggests that your method is the way to handle this.