Most developers should not have cause to use this module. Users who absolutely must have the functionality that domains provide may rely on it for the time being but should expect to have to migrate to a different solution in the future.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/nodejs/node/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Domains provide a way to handle multiple different IO operations as a single group. If any of the event emitters or callbacks registered to a domain emit an'error' event, or throw an error, then the domain object will be notified, rather than losing the context of the error in the process.on('uncaughtException') handler, or causing the program to exit immediately with an error code.
throw works in JavaScript, there is almost never any way to safely “pick up where it left off”, without leaking references, or creating some other sort of undefined brittle state.
The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, there may be many open connections, and it is not reasonable to abruptly shut those down because an error was triggered by someone else.
The better approach is to send an error response to the request that triggered the error, while letting the others finish in their normal time, and stop listening for new requests in that worker.
Best Practices
Domain usage should go hand-in-hand with the cluster module, since the primary process can fork a new worker when a worker encounters an error.API
domain.create()
Creates a new Domain instance. Returns: DomainClass: Domain
TheDomain class encapsulates the functionality of routing errors and uncaught exceptions to the active Domain object.
Extends: EventEmitter
Properties
domain.members
An array of event emitters that have been explicitly added to the domain. Type: ArrayMethods
domain.add(emitter)
Explicitly adds an emitter to the domain. If any event handlers called by the emitter throw an error, or if the emitter emits an'error' event, it will be routed to the domain’s 'error' event, just like with implicit binding.
Parameters:
emitter(EventEmitter) - Emitter to be added to the domain
EventEmitter was already bound to a domain, it is removed from that one, and bound to this one instead.
domain.bind(callback)
Returns a wrapper function around the supplied callback function. When the returned function is called, any errors that are thrown will be routed to the domain’s'error' event.
Parameters:
callback(Function) - The callback function
domain.enter()
Sets the active domain and pushes the domain onto the domain stack. Used byrun(), bind(), and intercept() methods to set the active domain.
domain.exit()
Exits the current domain, popping it off the domain stack. Any time execution is going to switch to the context of a different chain of asynchronous calls, it’s important to ensure that the current domain is exited.domain.intercept(callback)
Almost identical todomain.bind(callback). However, in addition to catching thrown errors, it will also intercept Error objects sent as the first argument to the function.
Parameters:
callback(Function) - The callback function
if (err) return callback(err); pattern to be replaced with a single error handler in a single place.
domain.remove(emitter)
The opposite ofdomain.add(emitter). Removes domain handling from the specified emitter.
Parameters:
emitter(EventEmitter) - Emitter to be removed from the domain
domain.run(fn[, …args])
Run the supplied function in the context of the domain, implicitly binding all event emitters, timers, and low-level requests that are created in that context. Optionally, arguments can be passed to the function. Parameters:fn(Function) - The function to run...args(any) - Optional arguments to pass to the function
Error Object Additions
Any time anError object is routed through a domain, a few extra fields are added to it:
error.domain- The domain that first handled the errorerror.domainEmitter- The event emitter that emitted an'error'event with the error objecterror.domainBound- The callback function which was bound to the domain, and passed an error as its first argumenterror.domainThrown- A boolean indicating whether the error was thrown, emitted, or passed to a bound callback function
Binding Types
Implicit Binding
If domains are in use, then all newEventEmitter objects (including Stream objects, requests, responses, etc.) will be implicitly bound to the active domain at the time of their creation.
Additionally, callbacks passed to low-level event loop requests (such as to fs.open(), or other callback-taking methods) will automatically be bound to the active domain. If they throw, then the domain will catch the error.
Implicit binding routes thrown errors and 'error' events to the Domain’s 'error' event, but does not register the EventEmitter on the Domain.
Explicit Binding
Sometimes, the domain in use is not the one that ought to be used for a specific event emitter. Or, the event emitter could have been created in the context of one domain, but ought to instead be bound to some other domain. For example, there could be one domain in use for an HTTP server, but perhaps we would like to have a separate domain to use for each request. That is possible via explicit binding.Domains and Promises
As of Node.js 8.0.0, the handlers of promises are run inside the domain in which the call to.then() or .catch() itself was made:
domain.bind(callback):
'error' event will be emitted for unhandled Promise rejections.