async-hook-domain
An implementation of the error-handling properties of the (deprecated) domain
node core module, re-implemented on top of
async_hooks
.
USAGE
const Domain = require('async-hook-domain')
const d = new Domain(er => {
console.log('caught an error', er)
})
setTimeout(() => {
throw new Error('this is caught by the domain a few lines up')
})
process.nextTick(() => {
const d2 = new Domain(er => {
console.log('any contexts spawned from this nextTick are caught here', er)
d2.destroy()
})
fs.readFile('does not exist', (er, data) => {
if (er)
throw er
})
fs.readFile('also does not exist', (er, data) => {
if (er)
throw er
})
})
const d3 = new Domain(er => console.log('d3', er))
Promise.reject(new Error('this will be handled by d3'))
setTimeout(() => {
d3.destroy()
throw new Error('this will be handled by the parent')
})
setTimeout(() => {
d.destroy()
throw new Error('this crashes the process like normal')
}, 500)
If you want to limit a Domain to a narrower scope, you can use node's
AsyncResource
class, and instantiate the domain within its runInAsyncScope(cb)
method.
From then on, the domain will only be active when running from that Async
Resource's scope.
API
process.env.ASYNC_HOOK_DOMAIN_DEBUG = '1'
Set the ASYNC_HOOK_DOMAIN_DEBUG
environment variable to '1'
to print a lot
of debugging information to stderr.
const d = new Domain(errorHandlerFunction(error, type))
Create a new Domain and assign it to the current execution context and all
child contexts that the current one triggers.
The handler function is called with two arguments. The first is the error that
was thrown or the rejection value of the rejected Promise. The second is
either 'uncaughtException'
or 'unhandledRejection'
, depending on the type
of event that raised the error.
d.parent Domain
If a Domain is already assigned to the current context on creation, then the
current Domain set as the new Domain's parent
. On destruction, any of a
Domain's still-active execution contexts are assigned to its parent.
d.onerror Function
The errorHandlerFunction
passed into the constructor. Called when an
uncaughtException or unhandledRejection occurs in the scope of the Domain.
If this function throws, then the domain will be destroyed, and the thrown
error will be raised. If the domain doesn't have a parent, then this will
likely crash the process entirely.
d.destroyed Boolean
Set to true
if the domain is destroyed.
d.ids Set
A set of the executionAsyncId
values corresponding to the execution contexts
for which this Domain handles errors.
d.destroy() Function
Call to destroy the domain. This removes it from the system entirely,
assigning any outstanding ids to its parent, if it has one, or leaving them
uncovered if not.
This is called implicitly when the domain's last covered execution context is
destroyed, since at that point, the domain is unreachable anyway.