Domain Module Postmortem
Evan Lucas
Domain Module Postmortem
Usability Issues
Implicit Behavior
It's possible for a developer to create a new domain and then simply run
domain.enter()
. Which then acts as a catch-all for any exception in the
future that couldn't be observed by the thrower. Allowing a module author to
intercept the exceptions of unrelated code in a different module. Preventing
the originator of the code from knowing about its own exceptions.
Here's an example of how one indirectly linked modules can affect another:
// module a.js
const import b
b = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('./b');
const import c
c = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('./c');
// module b.js
const const d: Domain
d = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('domain').function create(): Domain
create();
const d: Domain
d.NodeJS.EventEmitter<DefaultEventMap>.on<any>(eventName: string | symbol, listener: (...args: any[]) => void): Domain
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('error', () => {
/* silence everything */
});
const d: Domain
d.Domain.enter(): void
The `enter()` method is plumbing used by the `run()`, `bind()`, and `intercept()` methods to set the active domain. It sets `domain.active` and `process.domain` to the domain, and implicitly
pushes the domain onto the domain
stack managed by the domain module (see
{@link
exit
}
for details on the
domain stack). The call to `enter()` delimits the beginning of a chain of
asynchronous calls and I/O operations bound to a domain.
Calling `enter()` changes only the active domain, and does not alter the domain
itself. `enter()` and `exit()` can be called an arbitrary number of times on a
single domain.enter();
// module c.js
const import dep
dep = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('some-dep');
import dep
dep.method(); // Uh-oh! This method doesn't actually exist.
Since module b
enters the domain but never exits any uncaught exception will
be swallowed. Leaving module c
in the dark as to why it didn't run the entire
script. Leaving a potentially partially populated module.exports
. Doing this
is not the same as listening for 'uncaughtException'
. As the latter is
explicitly meant to globally catch errors. The other issue is that domains are
processed prior to any 'uncaughtException'
handlers, and prevent them from
running.
Another issue is that domains route errors automatically if no 'error'
handler was set on the event emitter. There is no opt-in mechanism for this,
and automatically propagates across the entire asynchronous chain. This may
seem useful at first, but once asynchronous calls are two or more modules deep
and one of them doesn't include an error handler the creator of the domain will
suddenly be catching unexpected exceptions, and the thrower's exception will go
unnoticed by the author.
The following is a simple example of how a missing 'error'
handler allows
the active domain to hijack the error:
const module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('domain');
const module "net"
> Stability: 2 - Stable
The `node:net` module provides an asynchronous network API for creating stream-based
TCP or `IPC` servers (
{@link
createServer
}
) and clients
(
{@link
createConnection
}
).
It can be accessed using:
```js
import net from 'node:net';
```net = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('net');
const const d: domain.Domain
d = module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.function create(): domain.Domain
create();
const d: domain.Domain
d.NodeJS.EventEmitter<DefaultEventMap>.on<any>(eventName: string | symbol, listener: (...args: any[]) => void): domain.Domain
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('error', err: any
err => var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.error(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stderr` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr
```
If formatting elements (e.g. `%d`) are not found in the first string then
[`util.inspect()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilinspectobject-options) is called on each argument and the
resulting string values are concatenated. See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)
for more information.error(err: any
err.message));
const d: domain.Domain
d.Domain.run<net.Server>(fn: (...args: any[]) => net.Server, ...args: any[]): net.Server
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.
This is the most basic way to use a domain.
```js
import domain from 'node:domain';
import fs from 'node:fs';
const d = domain.create();
d.on('error', (er) => {
console.error('Caught error!', er);
});
d.run(() => {
process.nextTick(() => {
setTimeout(() => { // Simulating some various async stuff
fs.open('non-existent file', 'r', (er, fd) => {
if (er) throw er;
// proceed...
});
}, 100);
});
});
```
In this example, the `d.on('error')` handler will be triggered, rather
than crashing the program.run(() =>
module "net"
> Stability: 2 - Stable
The `node:net` module provides an asynchronous network API for creating stream-based
TCP or `IPC` servers (
{@link
createServer
}
) and clients
(
{@link
createConnection
}
).
It can be accessed using:
```js
import net from 'node:net';
```net
.function createServer(connectionListener?: (socket: net.Socket) => void): net.Server (+1 overload)
Creates a new TCP or `IPC` server.
If `allowHalfOpen` is set to `true`, when the other end of the socket
signals the end of transmission, the server will only send back the end of
transmission when `socket.end()` is explicitly called. For example, in the
context of TCP, when a FIN packed is received, a FIN packed is sent
back only when `socket.end()` is explicitly called. Until then the
connection is half-closed (non-readable but still writable). See `'end'` event and [RFC 1122](https://tools.ietf.org/html/rfc1122) (section 4.2.2.13) for more information.
If `pauseOnConnect` is set to `true`, then the socket associated with each
incoming connection will be paused, and no data will be read from its handle.
This allows connections to be passed between processes without any data being
read by the original process. To begin reading data from a paused socket, call `socket.resume()`.
The server can be a TCP server or an `IPC` server, depending on what it `listen()` to.
Here is an example of a TCP echo server which listens for connections
on port 8124:
```js
import net from 'node:net';
const server = net.createServer((c) => {
// 'connection' listener.
console.log('client connected');
c.on('end', () => {
console.log('client disconnected');
});
c.write('hello\r\n');
c.pipe(c);
});
server.on('error', (err) => {
throw err;
});
server.listen(8124, () => {
console.log('server bound');
});
```
Test this by using `telnet`:
```bash
telnet localhost 8124
```
To listen on the socket `/tmp/echo.sock`:
```js
server.listen('/tmp/echo.sock', () => {
console.log('server bound');
});
```
Use `nc` to connect to a Unix domain socket server:
```bash
nc -U /tmp/echo.sock
```createServer(c: net.Socket
c => {
c: net.Socket
c.Socket.end(callback?: () => void): net.Socket (+2 overloads)
Half-closes the socket. i.e., it sends a FIN packet. It is possible the
server will still send some data.
See `writable.end()` for further details.end();
c: net.Socket
c.Socket.write(buffer: Uint8Array | string, cb?: (err?: Error | null) => void): boolean (+1 overload)
Sends data on the socket. The second parameter specifies the encoding in the
case of a string. It defaults to UTF8 encoding.
Returns `true` if the entire data was flushed successfully to the kernel
buffer. Returns `false` if all or part of the data was queued in user memory.`'drain'` will be emitted when the buffer is again free.
The optional `callback` parameter will be executed when the data is finally
written out, which may not be immediately.
See `Writable` stream `write()` method for more
information.write('bye');
})
.Server.listen(port?: number, hostname?: string, backlog?: number, listeningListener?: () => void): net.Server (+8 overloads)
Start a server listening for connections. A `net.Server` can be a TCP or
an `IPC` server depending on what it listens to.
Possible signatures:
* `server.listen(handle[, backlog][, callback])`
* `server.listen(options[, callback])`
* `server.listen(path[, backlog][, callback])` for `IPC` servers
* `server.listen([port[, host[, backlog]]][, callback])` for TCP servers
This function is asynchronous. When the server starts listening, the `'listening'` event will be emitted. The last parameter `callback`will be added as a listener for the `'listening'`
event.
All `listen()` methods can take a `backlog` parameter to specify the maximum
length of the queue of pending connections. The actual length will be determined
by the OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on Linux. The default value of this parameter is 511 (not 512).
All
{@link
Socket
}
are set to `SO_REUSEADDR` (see [`socket(7)`](https://man7.org/linux/man-pages/man7/socket.7.html) for
details).
The `server.listen()` method can be called again if and only if there was an
error during the first `server.listen()` call or `server.close()` has been
called. Otherwise, an `ERR_SERVER_ALREADY_LISTEN` error will be thrown.
One of the most common errors raised when listening is `EADDRINUSE`.
This happens when another server is already listening on the requested`port`/`path`/`handle`. One way to handle this would be to retry
after a certain amount of time:
```js
server.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
console.error('Address in use, retrying...');
setTimeout(() => {
server.close();
server.listen(PORT, HOST);
}, 1000);
}
});
```listen(8000)
);
Even manually removing the connection via d.remove(c)
does not prevent the
connection's error from being automatically intercepted.
Failures that plagues both error routing and exception handling are the inconsistencies in how errors are bubbled. The following is an example of how nested domains will and won't bubble the exception based on when they happen:
const module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('domain');
const module "net"
> Stability: 2 - Stable
The `node:net` module provides an asynchronous network API for creating stream-based
TCP or `IPC` servers (
{@link
createServer
}
) and clients
(
{@link
createConnection
}
).
It can be accessed using:
```js
import net from 'node:net';
```net = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('net');
const const d: domain.Domain
d = module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.function create(): domain.Domain
create();
const d: domain.Domain
d.NodeJS.EventEmitter<DefaultEventMap>.on<any>(eventName: string | symbol, listener: (...args: any[]) => void): domain.Domain
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('error', () => var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.error(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stderr` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr
```
If formatting elements (e.g. `%d`) are not found in the first string then
[`util.inspect()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilinspectobject-options) is called on each argument and the
resulting string values are concatenated. See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)
for more information.error('d intercepted an error'));
const d: domain.Domain
d.Domain.run<void>(fn: (...args: any[]) => void, ...args: any[]): void
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.
This is the most basic way to use a domain.
```js
import domain from 'node:domain';
import fs from 'node:fs';
const d = domain.create();
d.on('error', (er) => {
console.error('Caught error!', er);
});
d.run(() => {
process.nextTick(() => {
setTimeout(() => { // Simulating some various async stuff
fs.open('non-existent file', 'r', (er, fd) => {
if (er) throw er;
// proceed...
});
}, 100);
});
});
```
In this example, the `d.on('error')` handler will be triggered, rather
than crashing the program.run(() => {
const const server: net.Server
server = module "net"
> Stability: 2 - Stable
The `node:net` module provides an asynchronous network API for creating stream-based
TCP or `IPC` servers (
{@link
createServer
}
) and clients
(
{@link
createConnection
}
).
It can be accessed using:
```js
import net from 'node:net';
```net
.function createServer(connectionListener?: (socket: net.Socket) => void): net.Server (+1 overload)
Creates a new TCP or `IPC` server.
If `allowHalfOpen` is set to `true`, when the other end of the socket
signals the end of transmission, the server will only send back the end of
transmission when `socket.end()` is explicitly called. For example, in the
context of TCP, when a FIN packed is received, a FIN packed is sent
back only when `socket.end()` is explicitly called. Until then the
connection is half-closed (non-readable but still writable). See `'end'` event and [RFC 1122](https://tools.ietf.org/html/rfc1122) (section 4.2.2.13) for more information.
If `pauseOnConnect` is set to `true`, then the socket associated with each
incoming connection will be paused, and no data will be read from its handle.
This allows connections to be passed between processes without any data being
read by the original process. To begin reading data from a paused socket, call `socket.resume()`.
The server can be a TCP server or an `IPC` server, depending on what it `listen()` to.
Here is an example of a TCP echo server which listens for connections
on port 8124:
```js
import net from 'node:net';
const server = net.createServer((c) => {
// 'connection' listener.
console.log('client connected');
c.on('end', () => {
console.log('client disconnected');
});
c.write('hello\r\n');
c.pipe(c);
});
server.on('error', (err) => {
throw err;
});
server.listen(8124, () => {
console.log('server bound');
});
```
Test this by using `telnet`:
```bash
telnet localhost 8124
```
To listen on the socket `/tmp/echo.sock`:
```js
server.listen('/tmp/echo.sock', () => {
console.log('server bound');
});
```
Use `nc` to connect to a Unix domain socket server:
```bash
nc -U /tmp/echo.sock
```createServer(c: net.Socket
c => {
const const e: domain.Domain
e = module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.function create(): domain.Domain
create(); // No 'error' handler being set.
const e: domain.Domain
e.Domain.run<never>(fn: (...args: any[]) => never, ...args: any[]): never
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.
This is the most basic way to use a domain.
```js
import domain from 'node:domain';
import fs from 'node:fs';
const d = domain.create();
d.on('error', (er) => {
console.error('Caught error!', er);
});
d.run(() => {
process.nextTick(() => {
setTimeout(() => { // Simulating some various async stuff
fs.open('non-existent file', 'r', (er, fd) => {
if (er) throw er;
// proceed...
});
}, 100);
});
});
```
In this example, the `d.on('error')` handler will be triggered, rather
than crashing the program.run(() => {
// This will not be caught by d's error handler.
function setImmediate<[]>(callback: () => void): NodeJS.Immediate (+1 overload)
Schedules the "immediate" execution of the `callback` after I/O events'
callbacks.
When multiple calls to `setImmediate()` are made, the `callback` functions are
queued for execution in the order in which they are created. The entire callback
queue is processed every event loop iteration. If an immediate timer is queued
from inside an executing callback, that timer will not be triggered until the
next event loop iteration.
If `callback` is not a function, a `TypeError` will be thrown.
This method has a custom variant for promises that is available using
`timersPromises.setImmediate()`.setImmediate(() => {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error('thrown from setImmediate');
});
// Though this one will bubble to d's error handler.
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error('immediately thrown');
});
})
.Server.listen(port?: number, hostname?: string, backlog?: number, listeningListener?: () => void): net.Server (+8 overloads)
Start a server listening for connections. A `net.Server` can be a TCP or
an `IPC` server depending on what it listens to.
Possible signatures:
* `server.listen(handle[, backlog][, callback])`
* `server.listen(options[, callback])`
* `server.listen(path[, backlog][, callback])` for `IPC` servers
* `server.listen([port[, host[, backlog]]][, callback])` for TCP servers
This function is asynchronous. When the server starts listening, the `'listening'` event will be emitted. The last parameter `callback`will be added as a listener for the `'listening'`
event.
All `listen()` methods can take a `backlog` parameter to specify the maximum
length of the queue of pending connections. The actual length will be determined
by the OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on Linux. The default value of this parameter is 511 (not 512).
All
{@link
Socket
}
are set to `SO_REUSEADDR` (see [`socket(7)`](https://man7.org/linux/man-pages/man7/socket.7.html) for
details).
The `server.listen()` method can be called again if and only if there was an
error during the first `server.listen()` call or `server.close()` has been
called. Otherwise, an `ERR_SERVER_ALREADY_LISTEN` error will be thrown.
One of the most common errors raised when listening is `EADDRINUSE`.
This happens when another server is already listening on the requested`port`/`path`/`handle`. One way to handle this would be to retry
after a certain amount of time:
```js
server.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
console.error('Address in use, retrying...');
setTimeout(() => {
server.close();
server.listen(PORT, HOST);
}, 1000);
}
});
```listen(8080);
});
It may be expected that nested domains always remain nested, and will always propagate the exception up the domain stack. Or that exceptions will never automatically bubble. Unfortunately both these situations occur, leading to potentially confusing behavior that may even be prone to difficult to debug timing conflicts.
API Gaps
While APIs based on using EventEmitter
can use bind()
and errback style
callbacks can use intercept()
, alternative APIs that implicitly bind to the
active domain must be executed inside of run()
. Meaning if module authors
wanted to support domains using a mechanism alternative to those mentioned they
must manually implement domain support themselves. Instead of being able to
leverage the implicit mechanisms already in place.
Error Propagation
Propagating errors across nested domains is not straight forward, if even
possible. Existing documentation shows a simple example of how to close()
an
http
server if there is an error in the request handler. What it does not
explain is how to close the server if the request handler creates another
domain instance for another async request. Using the following as a simple
example of the failing of error propagation:
const module d1
const d1: any
d1 = domain.create();
module d1
const d1: any
d1.foo = true; // custom member to make more visible in console
module d1
const d1: any
d1.on('error', er: any
er => {
/* handle error */
});
module d1
const d1: any
d1.run(() =>
function setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+2 overloads)
Schedules execution of a one-time `callback` after `delay` milliseconds.
The `callback` will likely not be invoked in precisely `delay` milliseconds.
Node.js makes no guarantees about the exact timing of when callbacks will fire,
nor of their ordering. The callback will be called as close as possible to the
time specified.
When `delay` is larger than `2147483647` or less than `1` or `NaN`, the `delay`
will be set to `1`. Non-integer delays are truncated to an integer.
If `callback` is not a function, a `TypeError` will be thrown.
This method has a custom variant for promises that is available using
`timersPromises.setTimeout()`.setTimeout(() => {
const const d2: any
d2 = domain.create();
const d2: any
d2.bar = 43;
const d2: any
d2.on('error', er: any
er => var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.error(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stderr` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr
```
If formatting elements (e.g. `%d`) are not found in the first string then
[`util.inspect()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilinspectobject-options) is called on each argument and the
resulting string values are concatenated. See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)
for more information.error(er: any
er.message, domain._stack));
const d2: any
d2.run(() => {
function setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+2 overloads)
Schedules execution of a one-time `callback` after `delay` milliseconds.
The `callback` will likely not be invoked in precisely `delay` milliseconds.
Node.js makes no guarantees about the exact timing of when callbacks will fire,
nor of their ordering. The callback will be called as close as possible to the
time specified.
When `delay` is larger than `2147483647` or less than `1` or `NaN`, the `delay`
will be set to `1`. Non-integer delays are truncated to an integer.
If `callback` is not a function, a `TypeError` will be thrown.
This method has a custom variant for promises that is available using
`timersPromises.setTimeout()`.setTimeout(() => {
function setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+2 overloads)
Schedules execution of a one-time `callback` after `delay` milliseconds.
The `callback` will likely not be invoked in precisely `delay` milliseconds.
Node.js makes no guarantees about the exact timing of when callbacks will fire,
nor of their ordering. The callback will be called as close as possible to the
time specified.
When `delay` is larger than `2147483647` or less than `1` or `NaN`, the `delay`
will be set to `1`. Non-integer delays are truncated to an integer.
If `callback` is not a function, a `TypeError` will be thrown.
This method has a custom variant for promises that is available using
`timersPromises.setTimeout()`.setTimeout(() => {
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error('outer');
});
throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error('inner');
});
});
})
);
Even in the case that the domain instances are being used for local storage so
access to resources are made available there is still no way to allow the error
to continue propagating from d2
back to d1
. Quick inspection may tell us
that simply throwing from d2
's domain 'error'
handler would allow d1
to
then catch the exception and execute its own error handler. Though that is not
the case. Upon inspection of domain._stack
you'll see that the stack only
contains d2
.
This may be considered a failing of the API, but even if it did operate in this
way there is still the issue of transmitting the fact that a branch in the
asynchronous execution has failed, and that all further operations in that
branch must cease. In the example of the http request handler, if we fire off
several asynchronous requests and each one then write()
's data back to the
client many more errors will arise from attempting to write()
to a closed
handle. More on this in Resource Cleanup on Exception.
Resource Cleanup on Exception
The following script contains a more complex example of properly cleaning up in a small resource dependency tree in the case that an exception occurs in a given connection or any of its dependencies. Breaking down the script into its basic operations:
'use strict';
const module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('domain');
const class EE<T extends EventMap<T> = DefaultEventMap>
The `EventEmitter` class is defined and exposed by the `node:events` module:
```js
import { EventEmitter } from 'node:events';
```
All `EventEmitter`s emit the event `'newListener'` when new listeners are
added and `'removeListener'` when existing listeners are removed.
It supports the following option:EE = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('events');
const module "fs"
The `node:fs` module enables interacting with the file system in a
way modeled on standard POSIX functions.
To use the promise-based APIs:
```js
import * as fs from 'node:fs/promises';
```
To use the callback and sync APIs:
```js
import * as fs from 'node:fs';
```
All file system operations have synchronous, callback, and promise-based
forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).fs = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('fs');
const module "net"
> Stability: 2 - Stable
The `node:net` module provides an asynchronous network API for creating stream-based
TCP or `IPC` servers (
{@link
createServer
}
) and clients
(
{@link
createConnection
}
).
It can be accessed using:
```js
import net from 'node:net';
```net = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('net');
const module "util"
The `node:util` module supports the needs of Node.js internal APIs. Many of the
utilities are useful for application and module developers as well. To access
it:
```js
import util from 'node:util';
```util = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('util');
const const print: any
print = var process: NodeJS.Process
process._rawDebug;
const const pipeList: any[]
pipeList = [];
const const FILENAME: "/tmp/tmp.tmp"
FILENAME = '/tmp/tmp.tmp';
const const PIPENAME: "/tmp/node-domain-example-"
PIPENAME = '/tmp/node-domain-example-';
const const FILESIZE: 1024
FILESIZE = 1024;
var var uid: number
uid = 0;
// Setting up temporary resources
const const buf: any
buf = var Buffer: BufferConstructor
Buffer(const FILESIZE: 1024
FILESIZE);
for (var var i: number
i = 0; var i: number
i < const buf: any
buf.length; var i: number
i++) const buf: any
buf[var i: number
i] = ((var Math: Math
An intrinsic object that provides basic mathematics functionality and constants.Math.Math.random(): number
Returns a pseudorandom number between 0 and 1.random() * 1e3) % 78) + 48; // Basic ASCII
module "fs"
The `node:fs` module enables interacting with the file system in a
way modeled on standard POSIX functions.
To use the promise-based APIs:
```js
import * as fs from 'node:fs/promises';
```
To use the callback and sync APIs:
```js
import * as fs from 'node:fs';
```
All file system operations have synchronous, callback, and promise-based
forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).fs.function writeFileSync(file: fs.PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView, options?: fs.WriteFileOptions): void
Returns `undefined`.
The `mode` option only affects the newly created file. See
{@link
open
}
for more details.
For detailed information, see the documentation of the asynchronous version of
this API:
{@link
writeFile
}
.writeFileSync(const FILENAME: "/tmp/tmp.tmp"
FILENAME, const buf: any
buf);
function function ConnectionResource(c: any): void
ConnectionResource(c: any
c) {
class EE<T extends EventMap<T> = DefaultEventMap>
The `EventEmitter` class is defined and exposed by the `node:events` module:
```js
import { EventEmitter } from 'node:events';
```
All `EventEmitter`s emit the event `'newListener'` when new listeners are
added and `'removeListener'` when existing listeners are removed.
It supports the following option:EE.NewableFunction.call<EE<EventMap<any>>, []>(this: new () => EE<EventMap<any>>, thisArg: EE<EventMap<any>>): void
Calls the function with the specified object as the this value and the specified rest arguments as the arguments.call(this);
this.ConnectionResource._connection: any
_connection = c: any
c;
this.ConnectionResource._alive: any
_alive = true;
this.ConnectionResource._domain: any
_domain = module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.function create(): domain.Domain
create();
this.ConnectionResource._id: any
_id = var Math: Math
An intrinsic object that provides basic mathematics functionality and constants.Math.Math.random(): number
Returns a pseudorandom number between 0 and 1.random().Number.toString(radix?: number): string
Returns a string representation of an object.toString(32).String.substr(from: number, length?: number): string
Gets a substring beginning at the specified location and having the specified length.substr(2).String.substr(from: number, length?: number): string
Gets a substring beginning at the specified location and having the specified length.substr(0, 8) + ++var uid: number
uid;
this.ConnectionResource._domain: domain.Domain
_domain.Domain.add(emitter: EE | NodeJS.Timer): void
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.
This also works with timers that are returned from `setInterval()` and `setTimeout()`. If their callback function throws, it will be caught by
the domain `'error'` handler.
If the Timer or `EventEmitter` was already bound to a domain, it is removed
from that one, and bound to this one instead.add(c: any
c);
this.ConnectionResource._domain: domain.Domain
_domain.NodeJS.EventEmitter<DefaultEventMap>.on<any>(eventName: string | symbol, listener: (...args: any[]) => void): domain.Domain
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('error', () => {
this.ConnectionResource._alive: boolean
_alive = false;
});
}
module "util"
The `node:util` module supports the needs of Node.js internal APIs. Many of the
utilities are useful for application and module developers as well. To access
it:
```js
import util from 'node:util';
```util.function inherits(constructor: unknown, superConstructor: unknown): void
Usage of `util.inherits()` is discouraged. Please use the ES6 `class` and
`extends` keywords to get language level inheritance support. Also note
that the two styles are [semantically incompatible](https://github.com/nodejs/node/issues/4179).
Inherit the prototype methods from one
[constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) into another. The
prototype of `constructor` will be set to a new object created from
`superConstructor`.
This mainly adds some input validation on top of
`Object.setPrototypeOf(constructor.prototype, superConstructor.prototype)`.
As an additional convenience, `superConstructor` will be accessible
through the `constructor.super_` property.
```js
const util = require('node:util');
const EventEmitter = require('node:events');
function MyStream() {
EventEmitter.call(this);
}
util.inherits(MyStream, EventEmitter);
MyStream.prototype.write = function(data) {
this.emit('data', data);
};
const stream = new MyStream();
console.log(stream instanceof EventEmitter); // true
console.log(MyStream.super_ === EventEmitter); // true
stream.on('data', (data) => {
console.log(`Received data: "${data}"`);
});
stream.write('It works!'); // Received data: "It works!"
```
ES6 example using `class` and `extends`:
```js
import EventEmitter from 'node:events';
class MyStream extends EventEmitter {
write(data) {
this.emit('data', data);
}
}
const stream = new MyStream();
stream.on('data', (data) => {
console.log(`Received data: "${data}"`);
});
stream.write('With ES6');
```inherits(class ConnectionResource
function ConnectionResource(c: any): void
ConnectionResource, class EE<T extends EventMap<T> = DefaultEventMap>
The `EventEmitter` class is defined and exposed by the `node:events` module:
```js
import { EventEmitter } from 'node:events';
```
All `EventEmitter`s emit the event `'newListener'` when new listeners are
added and `'removeListener'` when existing listeners are removed.
It supports the following option:EE);
class ConnectionResource
function ConnectionResource(c: any): void
ConnectionResource.Function.prototype: any
prototype.ConnectionResource.end(chunk: any): void
end = function function (local function) end(chunk: any): void
end(chunk: any
chunk) {
this.ConnectionResource._alive: boolean
_alive = false;
this.ConnectionResource._connection: any
_connection.end(chunk: any
chunk);
this.emit('end');
};
class ConnectionResource
function ConnectionResource(c: any): void
ConnectionResource.Function.prototype: any
prototype.ConnectionResource.isAlive(): boolean
isAlive = function function (local function) isAlive(): boolean
isAlive() {
return this.ConnectionResource._alive: boolean
_alive;
};
class ConnectionResource
function ConnectionResource(c: any): void
ConnectionResource.Function.prototype: any
prototype.ConnectionResource.id(): string
id = function function (local function) id(): string
id() {
return this.ConnectionResource._id: string
_id;
};
class ConnectionResource
function ConnectionResource(c: any): void
ConnectionResource.Function.prototype: any
prototype.ConnectionResource.write(chunk: any): any
write = function function (local function) write(chunk: any): any
write(chunk: any
chunk) {
this.emit('data', chunk: any
chunk);
return this.ConnectionResource._connection: any
_connection.write(chunk: any
chunk);
};
// Example begin
module "net"
> Stability: 2 - Stable
The `node:net` module provides an asynchronous network API for creating stream-based
TCP or `IPC` servers (
{@link
createServer
}
) and clients
(
{@link
createConnection
}
).
It can be accessed using:
```js
import net from 'node:net';
```net
.function createServer(connectionListener?: (socket: net.Socket) => void): net.Server (+1 overload)
Creates a new TCP or `IPC` server.
If `allowHalfOpen` is set to `true`, when the other end of the socket
signals the end of transmission, the server will only send back the end of
transmission when `socket.end()` is explicitly called. For example, in the
context of TCP, when a FIN packed is received, a FIN packed is sent
back only when `socket.end()` is explicitly called. Until then the
connection is half-closed (non-readable but still writable). See `'end'` event and [RFC 1122](https://tools.ietf.org/html/rfc1122) (section 4.2.2.13) for more information.
If `pauseOnConnect` is set to `true`, then the socket associated with each
incoming connection will be paused, and no data will be read from its handle.
This allows connections to be passed between processes without any data being
read by the original process. To begin reading data from a paused socket, call `socket.resume()`.
The server can be a TCP server or an `IPC` server, depending on what it `listen()` to.
Here is an example of a TCP echo server which listens for connections
on port 8124:
```js
import net from 'node:net';
const server = net.createServer((c) => {
// 'connection' listener.
console.log('client connected');
c.on('end', () => {
console.log('client disconnected');
});
c.write('hello\r\n');
c.pipe(c);
});
server.on('error', (err) => {
throw err;
});
server.listen(8124, () => {
console.log('server bound');
});
```
Test this by using `telnet`:
```bash
telnet localhost 8124
```
To listen on the socket `/tmp/echo.sock`:
```js
server.listen('/tmp/echo.sock', () => {
console.log('server bound');
});
```
Use `nc` to connect to a Unix domain socket server:
```bash
nc -U /tmp/echo.sock
```createServer(c: net.Socket
c => {
const const cr: ConnectionResource
cr = new constructor ConnectionResource(c: any): ConnectionResource
ConnectionResource(c: net.Socket
c);
const const d1: domain.Domain
d1 = module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.function create(): domain.Domain
create();
module "fs"
The `node:fs` module enables interacting with the file system in a
way modeled on standard POSIX functions.
To use the promise-based APIs:
```js
import * as fs from 'node:fs/promises';
```
To use the callback and sync APIs:
```js
import * as fs from 'node:fs';
```
All file system operations have synchronous, callback, and promise-based
forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).fs.function open(path: fs.PathLike, flags: fs.OpenMode | undefined, callback: (err: NodeJS.ErrnoException | null, fd: number) => void): void (+2 overloads)
Asynchronous open(2) - open and possibly create a file. If the file is created, its mode will be `0o666`.open(
const FILENAME: "/tmp/tmp.tmp"
FILENAME,
'r',
const d1: domain.Domain
d1.Domain.intercept<(fd: NodeJS.ErrnoException | null) => void>(callback: (fd: NodeJS.ErrnoException | null) => void): (fd: NodeJS.ErrnoException | null) => void
This method is almost identical to
{@link
bind
}
. However, in
addition to catching thrown errors, it will also intercept `Error` objects sent as the first argument to the function.
In this way, the common `if (err) return callback(err);` pattern can be replaced
with a single error handler in a single place.
```js
const d = domain.create();
function readSomeFile(filename, cb) {
fs.readFile(filename, 'utf8', d.intercept((data) => {
// Note, the first argument is never passed to the
// callback since it is assumed to be the 'Error' argument
// and thus intercepted by the domain.
// If this throws, it will also be passed to the domain
// so the error-handling logic can be moved to the 'error'
// event on the domain instead of being repeated throughout
// the program.
return cb(null, JSON.parse(data));
}));
}
d.on('error', (er) => {
// An error occurred somewhere. If we throw it now, it will crash the program
// with the normal line number and stack message.
});
```intercept(fd: NodeJS.ErrnoException | null
fd => {
function streamInParts(fd: any, cr: any, pos: any): void
streamInParts(fd: NodeJS.ErrnoException | null
fd, const cr: ConnectionResource
cr, 0);
})
);
function pipeData(cr: any): void
pipeData(const cr: ConnectionResource
cr);
c: net.Socket
c.Socket.on(event: "close", listener: (hadError: boolean) => void): net.Socket (+12 overloads)
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('close', () => const cr: ConnectionResource
cr.ConnectionResource.end(chunk: any): void
end());
})
.Server.listen(port?: number, hostname?: string, backlog?: number, listeningListener?: () => void): net.Server (+8 overloads)
Start a server listening for connections. A `net.Server` can be a TCP or
an `IPC` server depending on what it listens to.
Possible signatures:
* `server.listen(handle[, backlog][, callback])`
* `server.listen(options[, callback])`
* `server.listen(path[, backlog][, callback])` for `IPC` servers
* `server.listen([port[, host[, backlog]]][, callback])` for TCP servers
This function is asynchronous. When the server starts listening, the `'listening'` event will be emitted. The last parameter `callback`will be added as a listener for the `'listening'`
event.
All `listen()` methods can take a `backlog` parameter to specify the maximum
length of the queue of pending connections. The actual length will be determined
by the OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on Linux. The default value of this parameter is 511 (not 512).
All
{@link
Socket
}
are set to `SO_REUSEADDR` (see [`socket(7)`](https://man7.org/linux/man-pages/man7/socket.7.html) for
details).
The `server.listen()` method can be called again if and only if there was an
error during the first `server.listen()` call or `server.close()` has been
called. Otherwise, an `ERR_SERVER_ALREADY_LISTEN` error will be thrown.
One of the most common errors raised when listening is `EADDRINUSE`.
This happens when another server is already listening on the requested`port`/`path`/`handle`. One way to handle this would be to retry
after a certain amount of time:
```js
server.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
console.error('Address in use, retrying...');
setTimeout(() => {
server.close();
server.listen(PORT, HOST);
}, 1000);
}
});
```listen(8080);
function function streamInParts(fd: any, cr: any, pos: any): void
streamInParts(fd: any
fd, cr: any
cr, pos: any
pos) {
const const d2: domain.Domain
d2 = module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.function create(): domain.Domain
create();
var function (local var) alive: boolean
alive = true;
const d2: domain.Domain
d2.NodeJS.EventEmitter<DefaultEventMap>.on<any>(eventName: string | symbol, listener: (...args: any[]) => void): domain.Domain
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('error', er: any
er => {
const print: any
print('d2 error:', er: any
er.message);
cr: any
cr.end();
});
module "fs"
The `node:fs` module enables interacting with the file system in a
way modeled on standard POSIX functions.
To use the promise-based APIs:
```js
import * as fs from 'node:fs/promises';
```
To use the callback and sync APIs:
```js
import * as fs from 'node:fs';
```
All file system operations have synchronous, callback, and promise-based
forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).fs.function read<Buffer<ArrayBuffer>>(fd: number, buffer: Buffer<ArrayBuffer>, offset: number, length: number, position: fs.ReadPosition | null, callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffer: Buffer<...>) => void): void (+4 overloads)
Read data from the file specified by `fd`.
The callback is given the three arguments, `(err, bytesRead, buffer)`.
If the file is not modified concurrently, the end-of-file is reached when the
number of bytes read is zero.
If this method is invoked as its `util.promisify()` ed version, it returns
a promise for an `Object` with `bytesRead` and `buffer` properties.read(
fd: any
fd,
new var Buffer: BufferConstructor
new (size: number) => Buffer<ArrayBuffer> (+3 overloads)
Allocates a new buffer of {size} octets.Buffer(10),
0,
10,
pos: any
pos,
const d2: domain.Domain
d2.Domain.intercept<(bRead: NodeJS.ErrnoException | null, buf: number) => void>(callback: (bRead: NodeJS.ErrnoException | null, buf: number) => void): (bRead: NodeJS.ErrnoException | null, buf: number) => void
This method is almost identical to
{@link
bind
}
. However, in
addition to catching thrown errors, it will also intercept `Error` objects sent as the first argument to the function.
In this way, the common `if (err) return callback(err);` pattern can be replaced
with a single error handler in a single place.
```js
const d = domain.create();
function readSomeFile(filename, cb) {
fs.readFile(filename, 'utf8', d.intercept((data) => {
// Note, the first argument is never passed to the
// callback since it is assumed to be the 'Error' argument
// and thus intercepted by the domain.
// If this throws, it will also be passed to the domain
// so the error-handling logic can be moved to the 'error'
// event on the domain instead of being repeated throughout
// the program.
return cb(null, JSON.parse(data));
}));
}
d.on('error', (er) => {
// An error occurred somewhere. If we throw it now, it will crash the program
// with the normal line number and stack message.
});
```intercept((bRead: NodeJS.ErrnoException | null
bRead, buf: number
buf) => {
if (!cr: any
cr.isAlive()) {
return module "fs"
The `node:fs` module enables interacting with the file system in a
way modeled on standard POSIX functions.
To use the promise-based APIs:
```js
import * as fs from 'node:fs/promises';
```
To use the callback and sync APIs:
```js
import * as fs from 'node:fs';
```
All file system operations have synchronous, callback, and promise-based
forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).fs.function close(fd: number, callback?: fs.NoParamCallback): void
Closes the file descriptor. No arguments other than a possible exception are
given to the completion callback.
Calling `fs.close()` on any file descriptor (`fd`) that is currently in use
through any other `fs` operation may lead to undefined behavior.
See the POSIX [`close(2)`](http://man7.org/linux/man-pages/man2/close.2.html) documentation for more detail.close(fd: any
fd);
}
if (cr: any
cr._connection.bytesWritten < const FILESIZE: 1024
FILESIZE) {
// Documentation says callback is optional, but doesn't mention that if
// the write fails an exception will be thrown.
const const goodtogo: any
goodtogo = cr: any
cr.write(buf: number
buf);
if (const goodtogo: any
goodtogo) {
function setTimeout<[]>(callback: () => void, delay?: number): NodeJS.Timeout (+2 overloads)
Schedules execution of a one-time `callback` after `delay` milliseconds.
The `callback` will likely not be invoked in precisely `delay` milliseconds.
Node.js makes no guarantees about the exact timing of when callbacks will fire,
nor of their ordering. The callback will be called as close as possible to the
time specified.
When `delay` is larger than `2147483647` or less than `1` or `NaN`, the `delay`
will be set to `1`. Non-integer delays are truncated to an integer.
If `callback` is not a function, a `TypeError` will be thrown.
This method has a custom variant for promises that is available using
`timersPromises.setTimeout()`.setTimeout(() => function streamInParts(fd: any, cr: any, pos: any): void
streamInParts(fd: any
fd, cr: any
cr, pos: any
pos + bRead: NodeJS.ErrnoException | null
bRead), 1000);
} else {
cr: any
cr._connection.once('drain', () =>
function streamInParts(fd: any, cr: any, pos: any): void
streamInParts(fd: any
fd, cr: any
cr, pos: any
pos + bRead: NodeJS.ErrnoException | null
bRead)
);
}
return;
}
cr: any
cr.end(buf: number
buf);
module "fs"
The `node:fs` module enables interacting with the file system in a
way modeled on standard POSIX functions.
To use the promise-based APIs:
```js
import * as fs from 'node:fs/promises';
```
To use the callback and sync APIs:
```js
import * as fs from 'node:fs';
```
All file system operations have synchronous, callback, and promise-based
forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).fs.function close(fd: number, callback?: fs.NoParamCallback): void
Closes the file descriptor. No arguments other than a possible exception are
given to the completion callback.
Calling `fs.close()` on any file descriptor (`fd`) that is currently in use
through any other `fs` operation may lead to undefined behavior.
See the POSIX [`close(2)`](http://man7.org/linux/man-pages/man2/close.2.html) documentation for more detail.close(fd: any
fd);
})
);
}
function function pipeData(cr: any): void
pipeData(cr: any
cr) {
const const pname: string
pname = const PIPENAME: "/tmp/node-domain-example-"
PIPENAME + cr: any
cr.id();
const const ps: net.Server
ps = module "net"
> Stability: 2 - Stable
The `node:net` module provides an asynchronous network API for creating stream-based
TCP or `IPC` servers (
{@link
createServer
}
) and clients
(
{@link
createConnection
}
).
It can be accessed using:
```js
import net from 'node:net';
```net.function createServer(connectionListener?: (socket: net.Socket) => void): net.Server (+1 overload)
Creates a new TCP or `IPC` server.
If `allowHalfOpen` is set to `true`, when the other end of the socket
signals the end of transmission, the server will only send back the end of
transmission when `socket.end()` is explicitly called. For example, in the
context of TCP, when a FIN packed is received, a FIN packed is sent
back only when `socket.end()` is explicitly called. Until then the
connection is half-closed (non-readable but still writable). See `'end'` event and [RFC 1122](https://tools.ietf.org/html/rfc1122) (section 4.2.2.13) for more information.
If `pauseOnConnect` is set to `true`, then the socket associated with each
incoming connection will be paused, and no data will be read from its handle.
This allows connections to be passed between processes without any data being
read by the original process. To begin reading data from a paused socket, call `socket.resume()`.
The server can be a TCP server or an `IPC` server, depending on what it `listen()` to.
Here is an example of a TCP echo server which listens for connections
on port 8124:
```js
import net from 'node:net';
const server = net.createServer((c) => {
// 'connection' listener.
console.log('client connected');
c.on('end', () => {
console.log('client disconnected');
});
c.write('hello\r\n');
c.pipe(c);
});
server.on('error', (err) => {
throw err;
});
server.listen(8124, () => {
console.log('server bound');
});
```
Test this by using `telnet`:
```bash
telnet localhost 8124
```
To listen on the socket `/tmp/echo.sock`:
```js
server.listen('/tmp/echo.sock', () => {
console.log('server bound');
});
```
Use `nc` to connect to a Unix domain socket server:
```bash
nc -U /tmp/echo.sock
```createServer();
const const d3: domain.Domain
d3 = module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.function create(): domain.Domain
create();
const const connectionList: any[]
connectionList = [];
const d3: domain.Domain
d3.NodeJS.EventEmitter<DefaultEventMap>.on<any>(eventName: string | symbol, listener: (...args: any[]) => void): domain.Domain
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('error', er: any
er => {
const print: any
print('d3 error:', er: any
er.message);
cr: any
cr.end();
});
const d3: domain.Domain
d3.Domain.add(emitter: EE | NodeJS.Timer): void
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.
This also works with timers that are returned from `setInterval()` and `setTimeout()`. If their callback function throws, it will be caught by
the domain `'error'` handler.
If the Timer or `EventEmitter` was already bound to a domain, it is removed
from that one, and bound to this one instead.add(const ps: net.Server
ps);
const ps: net.Server
ps.Server.on(event: "connection", listener: (socket: net.Socket) => void): net.Server (+5 overloads)
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('connection', conn: net.Socket
conn => {
const connectionList: any[]
connectionList.Array<any>.push(...items: any[]): number
Appends new elements to the end of an array, and returns the new length of the array.push(conn: net.Socket
conn);
conn: net.Socket
conn.Socket.on(event: "data", listener: (data: Buffer) => void): net.Socket (+12 overloads)
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('data', () => {}); // don't care about incoming data.
conn: net.Socket
conn.Socket.on(event: "close", listener: (hadError: boolean) => void): net.Socket (+12 overloads)
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('close', () => {
const connectionList: any[]
connectionList.Array<any>.splice(start: number, deleteCount?: number): any[] (+1 overload)
Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.splice(const connectionList: any[]
connectionList.Array<any>.indexOf(searchElement: any, fromIndex?: number): number
Returns the index of the first occurrence of a value in an array, or -1 if it is not present.indexOf(conn: net.Socket
conn), 1);
});
});
cr: any
cr.on('data', chunk: any
chunk => {
for (var function (local var) i: number
i = 0; function (local var) i: number
i < const connectionList: any[]
connectionList.Array<any>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length; function (local var) i: number
i++) {
const connectionList: any[]
connectionList[function (local var) i: number
i].write(chunk: any
chunk);
}
});
cr: any
cr.on('end', () => {
for (var function (local var) i: number
i = 0; function (local var) i: number
i < const connectionList: any[]
connectionList.Array<any>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length; function (local var) i: number
i++) {
const connectionList: any[]
connectionList[function (local var) i: number
i].end();
}
const ps: net.Server
ps.Server.close(callback?: (err?: Error) => void): net.Server
Stops the server from accepting new connections and keeps existing
connections. This function is asynchronous, the server is finally closed
when all connections are ended and the server emits a `'close'` event.
The optional `callback` will be called once the `'close'` event occurs. Unlike
that event, it will be called with an `Error` as its only argument if the server
was not open when it was closed.close();
});
const pipeList: any[]
pipeList.Array<any>.push(...items: any[]): number
Appends new elements to the end of an array, and returns the new length of the array.push(const pname: string
pname);
const ps: net.Server
ps.Server.listen(path: string, backlog?: number, listeningListener?: () => void): net.Server (+8 overloads)
Start a server listening for connections. A `net.Server` can be a TCP or
an `IPC` server depending on what it listens to.
Possible signatures:
* `server.listen(handle[, backlog][, callback])`
* `server.listen(options[, callback])`
* `server.listen(path[, backlog][, callback])` for `IPC` servers
* `server.listen([port[, host[, backlog]]][, callback])` for TCP servers
This function is asynchronous. When the server starts listening, the `'listening'` event will be emitted. The last parameter `callback`will be added as a listener for the `'listening'`
event.
All `listen()` methods can take a `backlog` parameter to specify the maximum
length of the queue of pending connections. The actual length will be determined
by the OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on Linux. The default value of this parameter is 511 (not 512).
All
{@link
Socket
}
are set to `SO_REUSEADDR` (see [`socket(7)`](https://man7.org/linux/man-pages/man7/socket.7.html) for
details).
The `server.listen()` method can be called again if and only if there was an
error during the first `server.listen()` call or `server.close()` has been
called. Otherwise, an `ERR_SERVER_ALREADY_LISTEN` error will be thrown.
One of the most common errors raised when listening is `EADDRINUSE`.
This happens when another server is already listening on the requested`port`/`path`/`handle`. One way to handle this would be to retry
after a certain amount of time:
```js
server.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
console.error('Address in use, retrying...');
setTimeout(() => {
server.close();
server.listen(PORT, HOST);
}, 1000);
}
});
```listen(const pname: string
pname);
}
var process: NodeJS.Process
process.NodeJS.Process.on(event: NodeJS.Signals, listener: NodeJS.SignalsListener): NodeJS.Process (+12 overloads)
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('SIGINT', () => var process: NodeJS.Process
process.NodeJS.Process.exit(code?: number | string | null | undefined): never
The `process.exit()` method instructs Node.js to terminate the process
synchronously with an exit status of `code`. If `code` is omitted, exit uses
either the 'success' code `0` or the value of `process.exitCode` if it has been
set. Node.js will not terminate until all the `'exit'` event listeners are
called.
To exit with a 'failure' code:
```js
import { exit } from 'node:process';
exit(1);
```
The shell that executed Node.js should see the exit code as `1`.
Calling `process.exit()` will force the process to exit as quickly as possible
even if there are still asynchronous operations pending that have not yet
completed fully, including I/O operations to `process.stdout` and `process.stderr`.
In most situations, it is not actually necessary to call `process.exit()` explicitly. The Node.js process will exit on its own _if there is no additional_
_work pending_ in the event loop. The `process.exitCode` property can be set to
tell the process which exit code to use when the process exits gracefully.
For instance, the following example illustrates a _misuse_ of the `process.exit()` method that could lead to data printed to stdout being
truncated and lost:
```js
import { exit } from 'node:process';
// This is an example of what *not* to do:
if (someConditionNotMet()) {
printUsageToStdout();
exit(1);
}
```
The reason this is problematic is because writes to `process.stdout` in Node.js
are sometimes _asynchronous_ and may occur over multiple ticks of the Node.js
event loop. Calling `process.exit()`, however, forces the process to exit _before_ those additional writes to `stdout` can be performed.
Rather than calling `process.exit()` directly, the code _should_ set the `process.exitCode` and allow the process to exit naturally by avoiding
scheduling any additional work for the event loop:
```js
import process from 'node:process';
// How to properly set the exit code while letting
// the process exit gracefully.
if (someConditionNotMet()) {
printUsageToStdout();
process.exitCode = 1;
}
```
If it is necessary to terminate the Node.js process due to an error condition,
throwing an _uncaught_ error and allowing the process to terminate accordingly
is safer than calling `process.exit()`.
In `Worker` threads, this function stops the current thread rather
than the current process.exit());
var process: NodeJS.Process
process.NodeJS.Process.on(event: "exit", listener: NodeJS.ExitListener): NodeJS.Process (+12 overloads)
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('exit', () => {
try {
for (var function (local var) i: number
i = 0; function (local var) i: number
i < const pipeList: any[]
pipeList.Array<any>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.length; function (local var) i: number
i++) {
module "fs"
The `node:fs` module enables interacting with the file system in a
way modeled on standard POSIX functions.
To use the promise-based APIs:
```js
import * as fs from 'node:fs/promises';
```
To use the callback and sync APIs:
```js
import * as fs from 'node:fs';
```
All file system operations have synchronous, callback, and promise-based
forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).fs.function unlinkSync(path: fs.PathLike): void
Synchronous [`unlink(2)`](http://man7.org/linux/man-pages/man2/unlink.2.html). Returns `undefined`.unlinkSync(const pipeList: any[]
pipeList[function (local var) i: number
i]);
}
module "fs"
The `node:fs` module enables interacting with the file system in a
way modeled on standard POSIX functions.
To use the promise-based APIs:
```js
import * as fs from 'node:fs/promises';
```
To use the callback and sync APIs:
```js
import * as fs from 'node:fs';
```
All file system operations have synchronous, callback, and promise-based
forms, and are accessible using both CommonJS syntax and ES6 Modules (ESM).fs.function unlinkSync(path: fs.PathLike): void
Synchronous [`unlink(2)`](http://man7.org/linux/man-pages/man2/unlink.2.html). Returns `undefined`.unlinkSync(const FILENAME: "/tmp/tmp.tmp"
FILENAME);
} catch (function (local var) e: unknown
e) {}
});
- When a new connection happens, concurrently:
- Open a file on the file system
- Open Pipe to unique socket
- Read a chunk of the file asynchronously
- Write chunk to both the TCP connection and any listening sockets
- If any of these resources error, notify all other attached resources that they need to clean up and shutdown
As we can see from this example a lot more must be done to properly clean up resources when something fails than what can be done strictly through the domain API. All that domains offer is an exception aggregation mechanism. Even the potentially useful ability to propagate data with the domain is easily countered, in this example, by passing the needed resources as a function argument.
One problem domains perpetuated was the supposed simplicity of being able to continue execution, contrary to what the documentation stated, of the application despite an unexpected exception. This example demonstrates the fallacy behind that idea.
Attempting proper resource cleanup on unexpected exception becomes more complex as the application itself grows in complexity. This example only has 3 basic resources in play, and all of them with a clear dependency path. If an application uses something like shared resources or resource reuse the ability to cleanup, and properly test that cleanup has been done, grows greatly.
In the end, in terms of handling errors, domains aren't much more than a
glorified 'uncaughtException'
handler. Except with more implicit and
unobservable behavior by third-parties.
Resource Propagation
Another use case for domains was to use it to propagate data along asynchronous data paths. One problematic point is the ambiguity of when to expect the correct domain when there are multiple in the stack (which must be assumed if the async stack works with other modules). Also the conflict between being able to depend on a domain for error handling while also having it available to retrieve the necessary data.
The following is a involved example demonstrating the failing using domains to propagate data along asynchronous stacks:
const module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('domain');
const module "net"
> Stability: 2 - Stable
The `node:net` module provides an asynchronous network API for creating stream-based
TCP or `IPC` servers (
{@link
createServer
}
) and clients
(
{@link
createConnection
}
).
It can be accessed using:
```js
import net from 'node:net';
```net = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('net');
const const server: net.Server
server = module "net"
> Stability: 2 - Stable
The `node:net` module provides an asynchronous network API for creating stream-based
TCP or `IPC` servers (
{@link
createServer
}
) and clients
(
{@link
createConnection
}
).
It can be accessed using:
```js
import net from 'node:net';
```net
.function createServer(connectionListener?: (socket: net.Socket) => void): net.Server (+1 overload)
Creates a new TCP or `IPC` server.
If `allowHalfOpen` is set to `true`, when the other end of the socket
signals the end of transmission, the server will only send back the end of
transmission when `socket.end()` is explicitly called. For example, in the
context of TCP, when a FIN packed is received, a FIN packed is sent
back only when `socket.end()` is explicitly called. Until then the
connection is half-closed (non-readable but still writable). See `'end'` event and [RFC 1122](https://tools.ietf.org/html/rfc1122) (section 4.2.2.13) for more information.
If `pauseOnConnect` is set to `true`, then the socket associated with each
incoming connection will be paused, and no data will be read from its handle.
This allows connections to be passed between processes without any data being
read by the original process. To begin reading data from a paused socket, call `socket.resume()`.
The server can be a TCP server or an `IPC` server, depending on what it `listen()` to.
Here is an example of a TCP echo server which listens for connections
on port 8124:
```js
import net from 'node:net';
const server = net.createServer((c) => {
// 'connection' listener.
console.log('client connected');
c.on('end', () => {
console.log('client disconnected');
});
c.write('hello\r\n');
c.pipe(c);
});
server.on('error', (err) => {
throw err;
});
server.listen(8124, () => {
console.log('server bound');
});
```
Test this by using `telnet`:
```bash
telnet localhost 8124
```
To listen on the socket `/tmp/echo.sock`:
```js
server.listen('/tmp/echo.sock', () => {
console.log('server bound');
});
```
Use `nc` to connect to a Unix domain socket server:
```bash
nc -U /tmp/echo.sock
```createServer(c: net.Socket
c => {
// Use a domain to propagate data across events within the
// connection so that we don't have to pass arguments
// everywhere.
const const d: domain.Domain
d = module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.function create(): domain.Domain
create();
const d: domain.Domain
d.data = { connection: net.Socket
connection: c: net.Socket
c };
const d: domain.Domain
d.Domain.add(emitter: EventEmitter | NodeJS.Timer): void
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.
This also works with timers that are returned from `setInterval()` and `setTimeout()`. If their callback function throws, it will be caught by
the domain `'error'` handler.
If the Timer or `EventEmitter` was already bound to a domain, it is removed
from that one, and bound to this one instead.add(c: net.Socket
c);
// Mock class that does some useless async data transformation
// for demonstration purposes.
const const ds: DataStream
ds = new constructor DataStream(cb: any): DataStream
DataStream(function dataTransformed(chunk: any): void
dataTransformed);
c: net.Socket
c.Socket.on(event: "data", listener: (data: Buffer) => void): net.Socket (+12 overloads)
Adds the `listener` function to the end of the listeners array for the event
named `eventName`. No checks are made to see if the `listener` has already
been added. Multiple calls passing the same combination of `eventName` and
`listener` will result in the `listener` being added, and called, multiple times.
```js
server.on('connection', (stream) => {
console.log('someone connected!');
});
```
Returns a reference to the `EventEmitter`, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.
```js
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
```on('data', chunk: Buffer<ArrayBufferLike>
chunk => const ds: DataStream
ds.DataStream.data(chunk: any): void
data(chunk: Buffer<ArrayBufferLike>
chunk));
})
.Server.listen(port?: number, listeningListener?: () => void): net.Server (+8 overloads)
Start a server listening for connections. A `net.Server` can be a TCP or
an `IPC` server depending on what it listens to.
Possible signatures:
* `server.listen(handle[, backlog][, callback])`
* `server.listen(options[, callback])`
* `server.listen(path[, backlog][, callback])` for `IPC` servers
* `server.listen([port[, host[, backlog]]][, callback])` for TCP servers
This function is asynchronous. When the server starts listening, the `'listening'` event will be emitted. The last parameter `callback`will be added as a listener for the `'listening'`
event.
All `listen()` methods can take a `backlog` parameter to specify the maximum
length of the queue of pending connections. The actual length will be determined
by the OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on Linux. The default value of this parameter is 511 (not 512).
All
{@link
Socket
}
are set to `SO_REUSEADDR` (see [`socket(7)`](https://man7.org/linux/man-pages/man7/socket.7.html) for
details).
The `server.listen()` method can be called again if and only if there was an
error during the first `server.listen()` call or `server.close()` has been
called. Otherwise, an `ERR_SERVER_ALREADY_LISTEN` error will be thrown.
One of the most common errors raised when listening is `EADDRINUSE`.
This happens when another server is already listening on the requested`port`/`path`/`handle`. One way to handle this would be to retry
after a certain amount of time:
```js
server.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
console.error('Address in use, retrying...');
setTimeout(() => {
server.close();
server.listen(PORT, HOST);
}, 1000);
}
});
```listen(8080, () => var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.log(`listening on 8080`));
function function dataTransformed(chunk: any): void
dataTransformed(chunk: any
chunk) {
// FAIL! Because the DataStream instance also created a
// domain we have now lost the active domain we had
// hoped to use.
module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.active.data.connection.write(chunk: any
chunk);
}
function function DataStream(cb: any): void
DataStream(cb: any
cb) {
this.DataStream.cb: any
cb = cb: any
cb;
// DataStream wants to use domains for data propagation too!
// Unfortunately this will conflict with any domain that
// already exists.
this.DataStream.domain: any
domain = module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.function create(): domain.Domain
create();
this.DataStream.domain: domain.Domain
domain.data = { inst: this
inst: this };
}
class DataStream
function DataStream(cb: any): void
DataStream.Function.prototype: any
prototype.DataStream.data(chunk: any): void
data = function function (local function) data(chunk: any): void
data(chunk: any
chunk) {
// This code is self contained, but pretend it's a complex
// operation that crosses at least one other module. So
// passing along "this", etc., is not easy.
this.DataStream.domain: domain.Domain
domain.Domain.run<void>(fn: (...args: any[]) => void, ...args: any[]): void
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.
This is the most basic way to use a domain.
```js
import domain from 'node:domain';
import fs from 'node:fs';
const d = domain.create();
d.on('error', (er) => {
console.error('Caught error!', er);
});
d.run(() => {
process.nextTick(() => {
setTimeout(() => { // Simulating some various async stuff
fs.open('non-existent file', 'r', (er, fd) => {
if (er) throw er;
// proceed...
});
}, 100);
});
});
```
In this example, the `d.on('error')` handler will be triggered, rather
than crashing the program.run(function () {
// Simulate an async operation that does the data transform.
function setImmediate<[]>(callback: () => void): NodeJS.Immediate (+1 overload)
Schedules the "immediate" execution of the `callback` after I/O events'
callbacks.
When multiple calls to `setImmediate()` are made, the `callback` functions are
queued for execution in the order in which they are created. The entire callback
queue is processed every event loop iteration. If an immediate timer is queued
from inside an executing callback, that timer will not be triggered until the
next event loop iteration.
If `callback` is not a function, a `TypeError` will be thrown.
This method has a custom variant for promises that is available using
`timersPromises.setImmediate()`.setImmediate(() => {
for (var function (local var) i: number
i = 0; function (local var) i: number
i < chunk: any
chunk.length; function (local var) i: number
i++)
chunk: any
chunk[function (local var) i: number
i] = ((chunk: any
chunk[function (local var) i: number
i] + var Math: Math
An intrinsic object that provides basic mathematics functionality and constants.Math.Math.random(): number
Returns a pseudorandom number between 0 and 1.random() * 100) % 96) + 33;
// Grab the instance from the active domain and use that
// to call the user's callback.
const const self: any
self = module "domain"
**This module is pending deprecation.** Once a replacement API has been
finalized, this module will be fully deprecated. 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.
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.domain.active.data.inst;
const self: any
self.cb.call(const self: any
self, chunk: any
chunk);
});
});
};
The above shows that it is difficult to have more than one asynchronous API
attempt to use domains to propagate data. This example could possibly be fixed
by assigning parent: domain.active
in the DataStream
constructor. Then
restoring it via domain.active = domain.active.data.parent
just before the
user's callback is called. Also the instantiation of DataStream
in the
'connection'
callback must be run inside d.run()
, instead of simply using
d.add(c)
, otherwise there will be no active domain.
In short, for this to have a prayer of a chance usage would need to strictly adhere to a set of guidelines that would be difficult to enforce or test.
Performance Issues
A significant deterrent from using domains is the overhead. Using node's
built-in http benchmark, http_simple.js
, without domains it can handle over
22,000 requests/second. Whereas if it's run with NODE_USE_DOMAINS=1
that
number drops down to under 17,000 requests/second. In this case there is only
a single global domain. If we edit the benchmark so the http request callback
creates a new domain instance performance drops further to 15,000
requests/second.
While this probably wouldn't affect a server only serving a few hundred or even a thousand requests per second, the amount of overhead is directly proportional to the number of asynchronous requests made. So if a single connection needs to connect to several other services all of those will contribute to the overall latency of delivering the final product to the client.
Using AsyncWrap
and tracking the number of times
init
/pre
/post
/destroy
are called in the mentioned benchmark we find
that the sum of all events called is over 170,000 times per second. This means
even adding 1 microsecond overhead per call for any type of setup or tear down
will result in a 17% performance loss. Granted, this is for the optimized
scenario of the benchmark, but I believe this demonstrates the necessity for a
mechanism such as domain to be as cheap to run as possible.
Looking Ahead
The domain module has been soft deprecated since Dec 2014, but has not yet been
removed because node offers no alternative functionality at the moment. As of
this writing there is ongoing work building out the AsyncWrap
API and a
proposal for Zones being prepared for the TC39. At such time there is suitable
functionality to replace domains it will undergo the full deprecation cycle and
eventually be removed from core.