How to find which promises are unhandled in Node.js UnhandledPromiseRejectionWarning?

81,558

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

  1. Install

    npm i trace-unhandled
    
  2. Include in code

    require('trace-unhandled/register');
    
Share:
81,558

Related videos on Youtube

user1658162
Author by

user1658162

Updated on March 10, 2022

Comments

  • user1658162
    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
      jfriend00 almost 7 years
      You could use the Bluebird promise library and it would likely give you a stack trace.
    • YSK
      YSK almost 7 years
      Perhaps registering to Node's unhandledRejection event will help? See the docs. Your callback gets the Error object and the actual Promise, and I believe the Error object might hold a stack trace.
    • Jaromanda X
      Jaromanda X almost 7 years
      If 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
      user1658162 almost 7 years
      hi 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
      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
      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
      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
      Krishna over 2 years
      I don't understand why this is not a default behaviour..
  • Adam Reis
    Adam Reis over 6 years
    Logging error.stack (or in the above example reason.stack) gives you the full stack trace of the error.
  • keba
    keba over 6 years
    Thanks for putting process.on rather than server.on like in so many other examples I've found
  • ffxsam
    ffxsam about 6 years
    I wish I could say this worked, but it doesn't. I'm on Node 8.9.4.
  • Will Lovett
    Will Lovett about 6 years
    Using 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
    Jeremy about 6 years
    I 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
    smb over 5 years
    Tried this and it worked like a charm! Resolved my issue very quickly.
  • Jason Leach
    Jason Leach over 5 years
    I don't see any output that shows where the unhandled promise issue is.
  • user1063287
    user1063287 over 5 years
    I added this code to the top of my node app.js file and nothing is logged unfortunately. Node v10.13.0.
  • user1063287
    user1063287 over 5 years
    I added this to package.json start script and nothing was logged unfortunately. Node v10.13.0.
  • Sven Slootweg
    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
    Craig Brett almost 5 years
    I 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
    Sven Slootweg almost 5 years
    You'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
    joshuakcockrell about 4 years
    The 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
    Luke about 4 years
    If you are using ts-node then you have to set NODE_OPTIONS="--trace-warnings" to make it work
  • Luke
    Luke about 4 years
    If 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 instance reason.stack knowing that reason is undefined. It will show a longer stack including the source of issue
  • TaylanKammer
    TaylanKammer over 3 years
    Why 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
    Royal over 3 years
    Or use console.log( { reason } ) to have a better output of the log
  • Dustin M.
    Dustin M. about 3 years
    For those who are handling unhandledRejection in AWS Node.js Lambdas: adding process.removeAllListeners('unhandledRejection'); to your function before using this solution allows you to handle this type of error.
  • Wyck
    Wyck almost 3 years
    I tried this but error.stack is undefined for me. :( node v14.15.4
  • Michael2
    Michael2 almost 3 years
    This 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
    Kangur over 2 years
    Where to add this code if I'm testing React app with Jest?
  • Jonatas Walker
    Jonatas Walker over 2 years
    Beautiful, plug'n play!
  • jcollum
    jcollum almost 2 years
    Node 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)