The basics
// Right now async_wrap is an internal C++ module,
// thus require doesn't work.
var asyncWrap = process.binding('async_wrap');
// Think of `CallInitHook` as the property name
// and `kCallInitHook` as the way to access it
var kCallInitHook = 0;
var asyncHooksObject = {};
// Enable async wrap
asyncWrap.setupHooks(asyncHooksObject,
asyncInit, asyncBefore, asyncAfter);
// Enable async_wrap events (default 0)
// Must be set after `async_wrap.setupHooks` is called
asyncHooksObject[kCallInitHook] = 1;
function asyncInit() {
log('async_wrap: init');
}
function asyncBefore() {
log('async_wrap: before');
}
function asyncAfter() {
log('async_wrap: after');
}
log('user: before');
fs.open(__filename, 'r', function (err, fd) {
log('user: done');
});
log('user: after');
$ node the_basic.js
user: before
async_wrap: init
user: after
async_wrap: before
user: done
async_wrap: after
Error catching
function asyncBefore() {
log('async_wrap: before');
}
function asyncAfter() {
log('async_wrap: after');
}
fs.open(__filename, 'r', function () {
throw new Error('ups');
});
$ node leaky_error.js
async_wrap: init
async_wrap: before
/demos/leaky_error.js:33
throw new Error('ups');
^
Error: ups
at /demos/leaky_error.js:33:9
at FSReqWrap.oncomplete (fs.js:73:15)
function asyncBefore() {
process.on(
'uncaughtException', asyncError);
}
function asyncAfter() {
process.removeListener(
'uncaughtException', asyncError);
}
function asyncError(err) {
log('(catch error)', err.stack);
}
fs.open(__filename, 'r', function () {
throw new Error('ups');
});
$ node catch_error.js
(catch error) Error: ups
at /demos/catch_error.js:38:9
at FSReqWrap.oncomplete (fs.js:73:15)
Known issue
- By catching, the throw origin is removed
- Mutate the error, but let it bubble up
- For now, use:
process._fatalException
- Even more undocumented and private API
than async_wrap
!
var catchError = false;
function asyncBefore() {
catchError = true;
}
function asyncAfter() {
catchError = false;
}
var old = process._fatalException;
process._fatalException = function (e){
if (catchError)
e.stack = 'Mutate' + e.stack;
old.apply(process, arguments);
};
fs.open(__filename, 'r', function () {
throw new Error('ups');
});
$ node catch_error.js
/demos/mutate_error.js:41
throw new Error('ups');
^
MutateError: ups
at /demos/mutate_error.js:41:9
at FSReqWrap.oncomplete (fs.js:73:15)