Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I determine what causes an UnhandledPromiseRejectionWarning in Node.js?

I've structured my Node.js application around the async/await library and it has been working great most of the time. The only trouble I have with it is that whenever a promise isn't fulfilled I get some variation of the following error:

(node:83333) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: Cannot read property '_id' of null

I'm ussually able to locate the offending promise but it takes quite a bit of debugging sometimes. Is there a method I can use to check the line number of the unhandled promise? Would save me considerable headach.

like image 706
Patrick Connors Avatar asked Oct 26 '17 17:10

Patrick Connors


1 Answers

I suggest you set a global unhandledRejection handler at the very beginning of your entry file:

process.on('unhandledRejection', (reason, p) => { throw reason });

This way, even if you forget to catch the errors locally, you can still track them down easily.

Update

There seems to be some confusion as to how the above handler helps you. Basically, when you don't catch promise errors, node outputs that warning to the console. For whatever silly reason, node only outputs the error message without the stack. Setting up the handler and then rethrowing the error generates the stack and allows you to debug your code easier. Here's an example:

let test = () => new Promise((resolve, reject) => {
    throw new Error('Random Error'); // same as "reject(new Error('Random Error'));"
});

test();

Without the handler you get:

(node:20012) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Random Error

Then, we add the handler at the top of our file:

process.on('unhandledRejection', (reason, p) => { throw reason });

let test = () => new Promise((resolve, reject) => {
    throw new Error('Random Error'); // same as "reject(new Error('Random Error'));"
});

test();

Now we get a much nicer error stack:

(function (exports, require, module, __filename, __dirname) { process.on('unhandledRejection', (reason, p) => { throw reason });
                                                                                                                ^

Error: Random Error
    at Promise (S:\amir\test.js:5:9)
    at test (S:\amir\test.js:3:18)
    at Object.<anonymous> (S:\amir\test.js:8:1)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
like image 160
earthling Avatar answered Oct 16 '22 04:10

earthling