petkaantonov / bluebird

:bird: :zap: Bluebird is a full featured promise library with unmatched performance.
http://bluebirdjs.com
MIT License
20.45k stars 2.33k forks source link

long stack traces assumption #838

Closed jardakotesovec closed 9 years ago

jardakotesovec commented 9 years ago

Hi, I am currently trying to figure out if its possible to modify https://github.com/facebook/dataloader to get full stack trace.

Basically my question is if I create var promise1 = new Promise(resolve,reject) and pass another promise2 to the resolve function. Lets assume that promise2 got rejected somewhere deep. Do you think that I still should get long stack trace?

Currently problem in dataloader is that promise chain got broken, because dataloader resolve the value and pass it to new promise.

So I was trying to pass promise to that resolve function instead of actual value, but did not help. So wondering if that situation is considered.

jardakotesovec commented 9 years ago

Maybe if there is some explanation somewhere how long stack traces work in bluebird that would probably give me clue what I can achieve. Did not find details in docs.

felixfbecker commented 9 years ago

I think if you want to convert a non-bluebird promise/thenable use Promise.resolve(promise) and it should be converted to a bluebird promise and therefor get long stacktrace?

jardakotesovec commented 9 years ago

@felixfbecker thanks for response, but its all bluebird promises. Conversion is not the problem.

Maybe I just don't understand how long stack trace is created - if its somehow at the time when error occurs or its constructed when error is bubbling up through promise chain.

If its the first case I would understand why its not working, because at the time of the error there is just promise chain from dataloader down.

felixfbecker commented 9 years ago

Under node you'd have to set BLUEBIRD_DEBUG=1. I don't know how you enable long stack traces in browser...

petkaantonov commented 9 years ago

Long stack traces don't transfer over promise implementation boundaries, if you have:

bluebirdPromise1 -> bluebirdPromise2 -> bluebirdPromise3 -> promise/a+ promise -> bluebirdPromise4 -> bluebirdPromise5 ->bluebirdPromise6 -> error

then the long stack trace for error starts from bluebirdPromise4

jardakotesovec commented 9 years ago

@petkaantonov I am aware of that - I made sure that dataloader also use bluebird promise (by setting global.Promise = require('bluebird'). So I am pretty sure that in that chain was no non-bluebird promise.

Lets look at this chain:

bluebirdPromise1 -> bluebirdPromise2 -> bluebirdPromise3 -> bluebirdPromise4 (in Dataloader) -> bluebirdPromise5 ->bluebirdPromise6 -> error

I suspect that reason why stack traces stop in dataloader is that in time when error occurs there is only chain: bluebirdPromise4 (in Dataloader) -> bluebirdPromise5 ->bluebirdPromise6 -> error. Complete chain is created sometime after that. This comes to my original question - is long stack trace created in time when error occurs? Or composed step by step when error is bubbling up?

petkaantonov commented 9 years ago

Every promise contains a ._trace property that contains the stack trace when the promise was created. When an error happens, these traces are combined with the error's stack trace to create a long stack trace