async-wrap: no way to catch errors without changing the throw origin #669
Description
Consider some long stack trace module. It can use async_wrap
to manage the the callSite objects correctly and use the v8 Error
hooks to modify the .stack
property. However because v8 sets the .stack
property in a lazy way, it is necessary to do a try {} finally {}
around the callback.
See https://github.com/AndreasMadsen/trace/blob/master/trace.js#L53 for an example with the tracing
module.
An okay solution solution is to use the uncaughtException
event like this:
var asyncWrap = process.binding('async_wrap');
// Enable asyncWrap and call init hook function on async initialization
var asyncHooksObject = {};
var kCallInitHook = 0;
asyncWrap.setupHooks(
asyncHooksObject,
asyncFunctionInitialized,
asyncCallbackBefore,
asyncCallbackAfter);
asyncHooksObject[kCallInitHook] = 1;
function asyncFunctionInitialized() {}
function asyncCallbackBefore() {
process.once('uncaughtException', asyncCallbackError);
}
function asyncCallbackError(error) {
// Set stack by v8 magic
error.stack;
// changes throw origin, should not be necessary
throw error;
}
function asyncCallbackAfter() {
process.removeListener('uncaughtException', asyncCallbackError);
}
setTimeout(function () {
badluck();
}, 10);
However this changes the throw origin:
/Users/Andreas/Sites/node_modules/trace/test.js:26
throw error;
^
ReferenceError: badluck is not defined
at null._onTimeout (/Users/Andreas/Sites/node_modules/trace/test.js:34:3)
at Timer.listOnTimeout (timers.js:90:15)
If uncaughtException
isn't used then this is the error:
/Users/Andreas/Sites/node_modules/trace/test.js:34
badluck();
^
ReferenceError: badluck is not defined
at null._onTimeout (/Users/Andreas/Sites/node_modules/trace/test.js:34:3)
at Timer.listOnTimeout (timers.js:90:15)
This is much more informative. It would be really nice if async_wrap
or some other mechanism allowed something similar to the old tracing.addAsyncListener({ error: handler })
behaviour. Such that the throw origin can be preserved.
issue tracking: AndreasMadsen/trace#12
issue tracking: nodejs/diagnostics#7