Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make when/debug track stack jumps #109

Closed
briancavalier opened this issue Feb 16, 2013 · 10 comments
Closed

make when/debug track stack jumps #109

briancavalier opened this issue Feb 16, 2013 · 10 comments
Milestone

Comments

@briancavalier
Copy link
Member

As in #108. We've discussed a good bit on this previously, and it is doable, albeit tricky.

It would be nice if when/debug could produce meaningful stack traces from promise chains that span stack jumps.

  1. "meaningful" is key, and we need to define it.
  2. There are relationships here between the point at which a handler is registered, where it actually executes, and the "event" (fulfillment/rejection) that causes it to execute. What are those, and how do they help us define "meaningful"?
  3. We may want to limit how "far" we track, since this could get out of control quickly for long promise chains.
@renato-zannon
Copy link
Contributor

Maybe we could get a feel for what we really need if we had some minimal debugging functionality first. What if we used the name property of named functions to track the handlers that were already executed, would it help somehow?

promise
  .then(function doSomething() { /* ... */  })
  .then(function doSomethingElse() { /* ... */ })
  .then(function iWillFail() { /* ... */ });

/*
  Error: Chuck Norris told me to fail
  - doSomething
  - doSomethingElse
  - iWillFail
*/

Then, we can play with variables like the maximum size of the trace, and whether or not show the resolution/rejection values and the other handlers attached to the promise.

There's also another option: what if, instead of having a stack trace, we had an introspection API for these things? That way, the developer would be able to dig as deep as s/he thinks is valuable.

/cc @Twisol @gr2m

@briancavalier
Copy link
Member Author

It might be interesting to decouple this stuff even from when/debug by going with something like promises-aplus/unhandled-rejections-spec#2. That is, having when/debug simply feed information to some environment hooks, and also implement those environment hooks itself, to do the work of tracking stack jumps, recording info, etc. IOW, when/debug becomes both a client and implementor of the environment hooks. If someone else comes along and writes a better promise debugger that takes advantage of Promises/A+ environment hooks, we can offer an option to disable ours.

@briancavalier
Copy link
Member Author

Lots of good and relevant information is piling up over here

@briancavalier
Copy link
Member Author

There's also another option: what if, instead of having a stack trace, we had an introspection API for these things? That way, the developer would be able to dig as deep as s/he thinks is valuable.

This is potentially interesting as well. Either way, we need to collect the "right" information as the system runs, so step 1 seems like determining what the "right" information is. To get that discussion started, here's a short list of things that seem useful to collect, without worrying too much about how we'd do it :)

  1. Promise chain origin. In the simple case, this is when.defer() currently, but if multiple promise implementations are in play, this could be the point at which when.js becomes aware of a 3rd party promise, for example if someone calls when(aForeignPromise, ...);
  2. Rejection origin. Where is the line of code that triggered a promise to reject?
  3. Rejection escape. Where is/are the end(s) of a promise chain where a rejection escaped without being handled.

What else?

@briancavalier
Copy link
Member Author

Some good info in this G+ post on how to capture stack traces in v8 and possibly other engines.

@unscriptable
Copy link
Member

IE can be done with something like -- but hopefully more elegant than -- this SO post

@briancavalier
Copy link
Member Author

Cool. And I just remembered that stacktrace.js exists, which we may be able to use as inspiration.

@briancavalier
Copy link
Member Author

I've been playing with a very rough POC in this branch. I created a simple global API (currently hanging off console, but would be nice to find a better way) for reporting pending, rejected and previously-rejected-but-now-handled promises. when.js and when/monitor rendezvous on that API: when.js reports things, monitor collects them. It then matches the creation point of pending promises up with the rejection point of unhandled rejected promises, and outputs a list of all the currently know unhandled rejections.

It's rough, but it's an interesting experiment, and the code is pretty simple. I'm hoping this sparks some ideas of where we can go with it :)

@briancavalier
Copy link
Member Author

I merged the POC to the dev branch. It seems like it's on the right track, although still could use lots of testing and feedback. Most recently, I added the ability to track stack chains from parent to child promises. That allows it to synthesize "long" stack traces that cross stack jump boundaries. It's def not perfect, but getting better.

If you want to try it out, check out the test/monitor folder in the dev branch.

@briancavalier
Copy link
Member Author

This is now in dev and will be released in 2.2. See docs here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants