How to debug code based on promises in node?

I use the large Cujo When library to provide a Promises / A + implementation for my Node project, although this question is not node-specific.

Generally, when it's excellent: it allows me to write more convenient, readable code.

However, when my callbacks end unexpectedly (referring to the property of a null variable, etc.), the exceptions are effectively swallowed, such as, for example, according to the Promises / A + specification. Unfortunately, this means I get no feedback about the error (except that the callback stops at this point). No type of error or message, line number.

To illustrate:

// hypothetical asynchronous database query database.query(queryDetails).then(function(result) { var silly = 3.141592654; silly(); // TypeError: number is not a function! process(result); // this code is silently never executed }); 

I can come up with several (unacceptable) ways to solve this problem:

  • providing response failures for each then call (to output the cause / exception to the console)
  • wrapping all callback bodies in try-catch
  • clog the codebase with the help of 'sign logs' ala console.log('I got here 123')

Am I just doing it wrong? Of course, I'm not alone in finding debugged errors on promises. Is there an obvious solution that I am missing?

+7
javascript debugging promise
source share
2 answers

September 2016 Update: NodeJS 6.6.0+ and 7.0+ will automatically warn of unhandled failures. Run node with --trace-warnings to get reasonable stack traces. Still not as good as the bluebird gives you, but much better than before.


Ok, so we summarize the information from the comments and add some.

  • There is nothing in the Promises / A + specification that dictates how to deal with this problem. The specification addresses the minimum requirements for good interoperability between different promise libraries - so one promise library can consume promises created in another, and vice versa.
  • Several libraries solve this problem by including the .done method, which explicitly declares that the chain is complete, which leads to the rejection of non-displayable failures. Libraries such as When and Q solve the problem this way. For example, if your .then after .query was .done , you would get a long stack trace.
  • Newer, less naive implementations of promises, such as Bluebird, solve this problem by automatically calculating possibly unincluded failures and writing them out loud for you. They also give you a hook. When there is experimental support for this using a monitor.

Thus:

  require('when/monitor/console'); // when will now log async rejections used with // `then` , this is experimental in when. 

With bluebird

 Promise.longStackTraces(); // Bluebird always logs async rejections but with this // option it will stitch the asynchronous context stack // for you in your methods. 
  • With this behavior
  • ES6 promises' not specified. In relation to this, there are no explicit requirements for the original implementations. However, I know that vendors are working on this, and I expect engines to begin to understand this even in their own implementations.
+15
source share

This is how I detect when Promise was rejected on Node but not caught:

 if (typeof process === 'object') { process.on('unhandledRejection', (error, promise) => { console.error("== Node detected an unhandled rejection! =="); console.error(error.stack); }); } 

In addition to this, you can use this monkey shell to provide long stack traces for Node ES6 Promises . It produces similar output for Q longStackSupport . I would not recommend using it outside of development code due to performance issues. (It works for me in Node v4.4.1. I have not tested it in Chrome or Firefox yet.)

+9
source share

All Articles