How to find which promises are unhandled in Node.js UnhandledPromiseRejectionWarning?
Solution 1
listen unhandledRejection
event of process.
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
// application specific logging, throwing an error, or other logic here
});
Solution 2
The correct way to show a full stacktrace for unhandled ES6 Promise rejections, is to run Node.js with the --trace-warnings
flag. This will show the full stacktrace for every warning, without having to intercept the rejection from within your own code. For example:
node --trace-warnings app.js
Ensure that the trace-warnings
flag comes before the name of your .js
file! Otherwise, the flag will be interpreted as an argument to your script, and it will be ignored by Node.js itself.
If you want to actually handle unhandled rejections (eg. by logging them), then you might want to use my unhandled-rejection
module instead, which catches all the unhandled rejections for every major Promises implementation that supports it, with a single event handler.
That module supports Bluebird, ES6 Promises, Q, WhenJS, es6-promise
, then/promise
, and anything that conforms to any of the unhandled rejection specifications (full details in the documentation).
Solution 3
Logging with stack trace
If you are looking for more of a helpful error message. Try adding this to your node file. It should display the full stack trace where your crash is happening.
process.on('unhandledRejection', (error, p) => {
console.log('=== UNHANDLED REJECTION ===');
console.dir(error.stack);
});
Solution 4
This module allowed me to track down the culprit promise(s): https://www.npmjs.com/package/trace-unhandled
-
Install
npm i trace-unhandled
-
Include in code
require('trace-unhandled/register');
Related videos on Youtube
user1658162
Updated on March 10, 2022Comments
-
user1658162 about 2 years
Node.js from version 7 has async/await syntactic sugar for handling promises and now in my code the following warning comes up quite often:
(node:11057) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): ReferenceError: Error: Can't set headers after they are sent. (node:11057) 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.
Unfortunately there's no reference to the line where the catch is missing. Is there any way to find it without checking every try/catch block?
-
jfriend00 almost 7 yearsYou could use the Bluebird promise library and it would likely give you a stack trace.
-
YSK almost 7 yearsPerhaps registering to Node's
unhandledRejection
event will help? See the docs. Your callback gets theError
object and the actualPromise
, and I believe theError
object might hold a stack trace. -
Jaromanda X almost 7 yearsIf the two previous comments don't help, then
Can't set headers after they are sent.
should give you a clue where in your code it could be happening (i.e. somewhere you are setting headers after the headers would've been already sent - presumably because of a failing in understanding asynchronous code, but that's a guess) -
user1658162 almost 7 yearshi that messages helps for sure in finding where in the code the bug is, btw it's not as easy as knowing the line.
-
Adam Reis over 6 years@jfriend00 I use the Bluebird library, and it doesn't help with this problem either. Still get those messages, without stack trace/line numbers.
-
jfriend00 over 6 years@AdamReis - If it is a Bluebird promise that has an unhandled rejection and the library is properly configured to show long reject traces, it will show you everything you want to see. But, if the promise is not a Bluebird promise, there's nothing Bluebird can do about that. If you want help with your particular situation, you'd have to write your own question and include the actual code involved.
-
Adam Reis over 6 years@jfriend00 It turns out it was a situation where an async function was throwing an error -- those internal Node promises for async functions don't use Bluebird, ever, so having Bluebird doesn't help in that scenario.
-
Krishna over 2 yearsI don't understand why this is not a default behaviour..
-
-
Adam Reis over 6 yearsLogging
error.stack
(or in the above examplereason.stack
) gives you the full stack trace of the error. -
keba over 6 yearsThanks for putting
process.on
rather thanserver.on
like in so many other examples I've found -
ffxsam about 6 yearsI wish I could say this worked, but it doesn't. I'm on Node 8.9.4.
-
Will Lovett about 6 yearsUsing node 7.8.0 and all this gives me is a stack trace for a bunch of internal node modules. (node:10372) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): undefined at emitWarning (internal/process/promises.js:59:21) at emitPendingUnhandledRejections (internal/process/promises.js:86:11) at process._tickDomainCallback (internal/process/next_tick.js:136:7)
-
Jeremy about 6 yearsI tried the above code and got undefined for both reason, and p? Any suggestions? " Unhandled Rejection at: Promise { state: 'rejected', reason: undefined } reason: undefined "
-
smb over 5 yearsTried this and it worked like a charm! Resolved my issue very quickly.
-
Jason Leach over 5 yearsI don't see any output that shows where the unhandled promise issue is.
-
user1063287 over 5 yearsI added this code to the top of my node
app.js
file and nothing is logged unfortunately. Nodev10.13.0
. -
user1063287 over 5 yearsI added this to
package.json
start script and nothing was logged unfortunately. Nodev10.13.0
. -
Sven Slootweg over 5 years@user1063287 Ensure that the flag is in the correct place in your command. I've just added an update to the answer, to emphasize that it needs to go before the script name.
-
Craig Brett almost 5 yearsI just tried this, all I got was the stack trace of emitPendingUnhandledRejections, and I'm fairly sure the command was right, as I wasn't getting the stack trace of that before. Not sure this is helpful in these cases, but a fair try
-
Sven Slootweg almost 5 yearsYou're likely looking at the stack trace of the deprecation warning, not of the original unhandled error (which should be somewhere above the deprecation warning).
-
joshuakcockrell about 4 yearsThe only functional difference is doing a console.dir on the error's stack property. Quite a difference in output compared to the accepted answer.
-
Luke about 4 yearsIf you are using ts-node then you have to set NODE_OPTIONS="--trace-warnings" to make it work
-
Luke about 4 yearsIf this is not helpful because of for instance:
Unhandled Rejection at: Promise Promise { <rejected> undefined } reason: undefined.
then you can cause an error in the callback function on purpose by calling for instancereason.stack
knowing thatreason
is undefined. It will show a longer stack including the source of issue -
TaylanKammer over 3 yearsWhy the heck isn't this part of the default behavior of Node? I'm on v14.8.0 and it still shows the completely unhelpful messages even when I use
--trace-warnings
. -
Royal over 3 yearsOr use console.log( { reason } ) to have a better output of the log
-
Dustin M. about 3 yearsFor those who are handling
unhandledRejection
in AWS Node.js Lambdas: addingprocess.removeAllListeners('unhandledRejection');
to your function before using this solution allows you to handle this type of error. -
Wyck almost 3 yearsI tried this but
error.stack
isundefined
for me. :( node v14.15.4 -
Michael2 almost 3 yearsThis will only work when error is an instance of Error. It won't work if the promise is rejected with e.g. a string value:
throw "Some error"
-
Kangur over 2 yearsWhere to add this code if I'm testing React app with Jest?
-
Jonatas Walker over 2 yearsBeautiful, plug'n play!
-
jcollum almost 2 yearsNode 14.19.1: didn't help, still getting
at emitUnhandledRejectionWarning (internal/process/promises.js:170:15)
(and that's the closest I get to the actual line)