Skip to content

Instantly share code, notes, and snippets.

@spion

spion/test.js Secret

Last active December 31, 2015 21:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spion/356bfc9cc1089edd2e3b to your computer and use it in GitHub Desktop.
Save spion/356bfc9cc1089edd2e3b to your computer and use it in GitHub Desktop.
test-genny-co-stacks
var co = require('co');
var genny = require('genny');
genny.longStackSupport = true;
function errorish() {
return function throwy(cb) {
setTimeout(function() { cb(new Error("Oops")); });
}
}
function delay(t) { return function(cb) { setTimeout(cb, t); } }
co(function *(){
try {
var a = yield delay(500);
var b = yield errorish();
var c = yield delay(500);
console.log("OK");
} catch (e) {
console.error("--- co:");
console.error(e.stack);
}
})();
genny.run(function* (resume) {
try {
var a = yield setTimeout(resume(), 500);
var b = yield errorish()(resume());
var c = yield setTimeout(resume(), 500);
console.log("OK");
} catch (e) {
console.error("--- genny:");
console.error(e.stack);
}
});
➜ co node --harmony index.js
--- co:
Error: Oops
at null._onTimeout (/home/spion/Documents/tests/co/index.js:8:12)
at Timer.listOnTimeout (timers.js:124:15)
--- genny:
Error: Oops
at null._onTimeout (/home/spion/Documents/tests/co/index.js:8:12)
at Timer.listOnTimeout (timers.js:124:15)
From generator:
at /home/spion/Documents/tests/co/index.js:29:30
@Marak
Copy link

Marak commented Dec 19, 2013

How is it possible to get the correct stack trace here? Is it possible with current harmony support in node?

@mvasilkov
Copy link

You may want to emulate it with a decorator or something. V8 stack-tracing you out of a setTimeout sounds unlikely.

@spion
Copy link
Author

spion commented Dec 20, 2013

@Marak yes.

Its a techique pioneered (afaik) by Q, and addopted by genny as well as [Bluebird]((//github.com/petkaantonov/bluebird) . Bluebird takes this the furthest (has some clever optimizations, supports an entire chain of previous events)

It uses Error.captureStackTrace (or simply generating a new Error()) when resume() is called or when executing a promise. The stack traces are kept in memory. If a real error happens, they're appended to that real error's stack trace.

There is a performance and memory penalty involved - its most likely not usable in production. But its still super-useful in development.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment