Search code examples
javascriptnode.jspromisebluebirdes6-promise

request-promise stack trace from catch


I'm currently using 'request-promise' library for API calls from node-js, and struggling to get a correct call stack from the 'catch' function. After playing a bit with it, I noticed an interesting behavior which I can not explain. Say I have code:

.catch(err => {
  console.log(err.stack);
  console.log('!!!');
  console.log(new Error().stack);
});

And in the the console I actually see two totally different stack traces for the 'err' and 'new Error()' :

StatusCodeError: 404 - [object Object]
    at new StatusCodeError (C:\MyProject\request-promise\lib\errors.js:26:15)
    at Request.RP$callback [as _callback] (C:\MyProject\request-promise\lib\rp.js:68:32)
    at Request.self.callback (C:\MyProject\request-promise\node_modules\request\request.js:187:22)
    at Request.emit (events.js:110:17)
    at Request.<anonymous> (C:\MyProject\request-promise\node_modules\request\request.js:1048:10)
    at Request.emit (events.js:107:17)
    at IncomingMessage.<anonymous> (C:\MyProject\request-promise\node_modules\request\request.js:969:12)
    at IncomingMessage.emit (events.js:129:20)
    at _stream_readable.js:908:16
    at process._tickCallback (node.js:355:11)
!!!
Error
    at C:/MyProject/src/server/controllers/bookingController.js:81:19
    at tryCatcher (C:\MyProject\request-promise\node_modules\bluebird\js\main\util.js:26:23)
    at Promise._settlePromiseFromHandler (C:\MyProject\request-promise\node_modules\bluebird\js\main\promise.js:510:31)
    at Promise._settlePromiseAt (C:\MyProject\request-promise\node_modules\bluebird\js\main\promise.js:584:18)
    at Promise._settlePromises (C:\MyProject\request-promise\node_modules\bluebird\js\main\promise.js:700:14)
    at Async._drainQueue (C:\MyProject\request-promise\node_modules\bluebird\js\main\async.js:123:16)
    at Async._drainQueues (C:\MyProject\request-promise\node_modules\bluebird\js\main\async.js:133:10)
    at Immediate.Async.drainQueues [as _onImmediate] (C:\MyProject\request-promise\node_modules\bluebird\js\main\async.js:15:14)
    at processImmediate [as _immediateCallback] (timers.js:367:17)

As you can see, 'new Error()' gives more helpful info about the call stack, since it has

'C:/MyProject/src/server/controllers/bookingController.js'

I guess that is because 'err' exception was created with a previous tick, and therefore it's stack trace is not related to my 'bookingController.js' in any way.

Also, I see that 'request-promise' internally uses 'bluebird', so technically I could use Promise.longStackTraces().

Finally, my question: is there a smarter way to get a correct stack trace except using 'new Error().stack' trick, since Promise.longStackTraces() is too performace-heavy for production?


Solution

  • Well, nodejs provides a prettier way to catch actual stack on nodeJS, which suits my needs:

      let capturedStack = {};
      Error.captureStackTrace(capturedStack, writeStack);
      console.log(capturedStack.stack);