Skip to content

Help, version, and errors

parse() never prints and never exits. It returns an intent or a failure, and three helpers turn that result into text:

  • printHelp() renders help for a help intent.
  • printVersion() renders the version for a version intent.
  • printErrors() renders every issue in a failure.

Each helper returns a string. Your application decides where to print it and which exit code to use.

Switch on method and pass the intent to its helper:

import
var process: NodeJS.Process
process
from "node:process";
import {
function command<const N extends string, const E extends readonly Input[]>(start: Definition<N>, ...elements: E & Validate<CommandZero<N>, E>): Materialize<Fold<CommandZero<N>, Normalize<E>>>
command
,
function description(description: string): IdentityElement<Definition<string>>
description
,
function name<N extends string>(name: N): Definition<N>
name
,
function parse<const R extends AnyRoute>(route: R, input: Input): Parse<R>
parse
,
function printErrors(result: MethodNotAllowed | UnprocessableContent): string
printErrors
,
function printHelp<const H extends Help<RoutePath>>(intent: H): string
printHelp
,
function printVersion<const V extends Version<RoutePath>>(intent: V): string
printVersion
,
function route<const N extends string, const E extends readonly Input[]>(start: Definition<N>, ...elements: E & Validate<RouteZero<N>, E>): Materialize<Fold<RouteZero<N>, Normalize<E>>>
route
,
function version(semver: string): MethodElement<"version">
version
,
} from "@bomb.sh/router";
const
const app: Route<"gh", "version" | "help" | "execute", readonly [Done<{}, readonly [Route<"pr", "help", readonly [Done<{}, readonly [Route<"list", "help" | "execute", [Done<{}, []>]>]>]>]>]>
app
=
command<"gh", readonly [IdentityElement<Definition<string>>, MethodElement<"version">, Route<"pr", "help", readonly [Done<{}, readonly [Route<"list", "help" | "execute", [...]>]>]>]>(start: Definition<...>, elements_0: IdentityElement<...>, elements_1: MethodElement<...>, elements_2: Route<...>): Route<...>
command
(
name<"gh">(name: "gh"): Definition<"gh">
name
("gh"),
function description(description: string): IdentityElement<Definition<string>>
description
("Work seamlessly with GitHub from the command line."),
function version(semver: string): MethodElement<"version">
version
("2.62.0"),
route<"pr", readonly [IdentityElement<Definition<string>>, Route<"list", "help" | "execute", [Done<{}, []>]>]>(start: Definition<"pr">, elements_0: IdentityElement<...>, elements_1: Route<...>): Route<...>
route
(
name<"pr">(name: "pr"): Definition<"pr">
name
("pr"),
function description(description: string): IdentityElement<Definition<string>>
description
("Manage pull requests"),
command<"list", readonly [IdentityElement<Definition<string>>]>(start: Definition<"list">, elements_0: IdentityElement<Definition<string>>): Route<...>
command
(
name<"list">(name: "list"): Definition<"list">
name
("list"),
function description(description: string): IdentityElement<Definition<string>>
description
("List pull requests in a repository"),
),
),
);
const
const result: Parse<Route<"gh", "version" | "help" | "execute", readonly [Done<{}, readonly [Route<"pr", "help", readonly [Done<{}, readonly [Route<"list", "help" | "execute", [Done<{}, []>]>]>]>]>]>>
result
=
parse<Route<"gh", "version" | "help" | "execute", readonly [Done<{}, readonly [Route<"pr", "help", readonly [Done<{}, readonly [Route<"list", "help" | "execute", [Done<{}, []>]>]>]>]>]>>(route: Route<...>, input: Input): Parse<...>
parse
(
const app: Route<"gh", "version" | "help" | "execute", readonly [Done<{}, readonly [Route<"pr", "help", readonly [Done<{}, readonly [Route<"list", "help" | "execute", [Done<{}, []>]>]>]>]>]>
app
, {
argv: string[]
argv
:
var process: NodeJS.Process
process
.
NodeJS.Process.argv: string[]

The process.argv property returns an array containing the command-line arguments passed when the Node.js process was launched. The first element will be

execPath

. See process.argv0 if access to the original value of argv[0] is needed. The second element will be the path to the JavaScript file being executed. The remaining elements will be any additional command-line arguments.

For example, assuming the following script for process-args.js:

import { argv } from 'node:process';
// print process.argv
argv.forEach((val, index) => {
console.log(`${index}: ${val}`);
});

Launching the Node.js process as:

Terminal window
node process-args.js one two=three four

Would generate the output:

0: /usr/local/bin/node
1: /Users/mjr/work/node/process-args.js
2: one
3: two=three
4: four

@since ― v0.1.27

argv
.
Array<string>.slice(start?: number, end?: number): string[]

Returns a copy of a section of an array. For both start and end, a negative index can be used to indicate an offset from the end of the array. For example, -2 refers to the second to last element of the array.

@param ― start The beginning index of the specified portion of the array. If start is undefined, then the slice begins at index 0.

@param ― end The end index of the specified portion of the array. This is exclusive of the element at the index 'end'. If end is undefined, then the slice extends to the end of the array.

slice
(2) });
if (!
const result: Parse<Route<"gh", "version" | "help" | "execute", readonly [Done<{}, readonly [Route<"pr", "help", readonly [Done<{}, readonly [Route<"list", "help" | "execute", [Done<{}, []>]>]>]>]>]>>
result
.
ok: boolean
ok
) {
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 and process.stderr. 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 for more information.

Example using the global console:

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:

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

@see ― source

console
.
Console.error(message?: any, ...optionalParams: any[]): void

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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@since ― v0.1.100

error
(
function printErrors(result: MethodNotAllowed | UnprocessableContent): string
printErrors
(
const result: MethodNotAllowed | UnprocessableContent
result
));
var process: NodeJS.Process
process
.
NodeJS.Process.exit(code?: number | string | null): 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:

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:

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:

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.

@since ― v0.1.13

@param ― code The exit code. For string type, only integer strings (e.g.,'1') are allowed.

exit
(1);
}
if (
const result: Help<"/"> | Version<"/"> | Execute<"/", {
"/": {};
}> | Help<"/pr"> | Help<"/pr/list"> | Execute<"/pr/list", {
"/": {};
"/pr": {};
"/pr/list": {};
}>
result
.
Intent<M extends Method, P extends RoutePath>.method: "version" | "help" | "execute"
method
=== "help")
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 and process.stderr. 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 for more information.

Example using the global console:

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:

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

@see ― source

console
.
Console.log(message?: any, ...optionalParams: any[]): void

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) (the arguments are all passed to util.format()).

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() for more information.

@since ― v0.1.100

log
(
printHelp<Help<"/"> | Help<"/pr"> | Help<"/pr/list">>(intent: Help<"/"> | Help<"/pr"> | Help<"/pr/list">): string
printHelp
(
const result: Help<"/"> | Help<"/pr"> | Help<"/pr/list">
result
));
if (
const result: Help<"/"> | Version<"/"> | Execute<"/", {
"/": {};
}> | Help<"/pr"> | Help<"/pr/list"> | Execute<"/pr/list", {
"/": {};
"/pr": {};
"/pr/list": {};
}>
result
.
Intent<M extends Method, P extends RoutePath>.method: "version" | "help" | "execute"
method
=== "version")
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 and process.stderr. 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 for more information.

Example using the global console:

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:

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

@see ― source

console
.
Console.log(message?: any, ...optionalParams: any[]): void

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) (the arguments are all passed to util.format()).

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() for more information.

@since ― v0.1.100

log
(
printVersion<Version<"/">>(intent: Version<"/">): string
printVersion
(
const result: Version<"/">
result
));

gh --version prints:

gh 2.62.0

description() adds text to help. It works on command(), route(), option(), toggle(), and argument(). After adding described repo, browse, and copilot routes to the app above, gh --help prints:

gh 2.62.0
Work seamlessly with GitHub from the command line.
Usage:
gh [OPTIONS] [COMMAND]
Commands:
pr Manage pull requests
repo Manage repositories
browse Open the repository in the browser
copilot Ask Copilot for help
Options:
-h, --help Print help
-v, --version Print version

Help for a child route lists its own options. For a pr list command with described --state and --limit options and an undescribed --repo option, gh pr list --help prints:

pr list
List pull requests in a repository
Usage:
pr list [OPTIONS]
Options:
--repo, -R <VALUE>
--state <VALUE> Filter by state
--limit, -L <VALUE> Maximum number of pull requests to fetch
-h, --help Print help

Positional arguments get their own section. For a repo clone command with a described repository argument, gh repo clone --help prints:

repo clone
Clone a repository locally
Usage:
repo clone [OPTIONS] <REPOSITORY>
Arguments:
<REPOSITORY> Repository to clone
Options:
-h, --help Print help

Help shows every option value as <VALUE> and does not show schema defaults. If users need to know a default or a format, put it in the description.

A failure has one of two codes:

  • method-not-allowed means the route does not support the requested method. See Routes and methods.
  • unprocessable-content means the input could not become a valid model.

printErrors() prints one line per issue. Unexpected input comes first, then schema issues prefixed with the parameter name. gh pr list --state draft --limit lots bogus prints:

unexpected: `bogus`
state: Invalid option: expected one of "open"|"closed"|"merged"|"all"
limit: Invalid input: expected number, received string

The router reports every issue it finds, not only the first one, so the user can fix them all at once.

To format failures your own way, narrow on code. An unprocessable-content failure has an issues list of Standard Schema issues, each with a message and an optional path. A method-not-allowed failure has the requested method and the allowed methods instead:

import
var process: NodeJS.Process
process
from "node:process";
import {
function command<const N extends string, const E extends readonly Input[]>(start: Definition<N>, ...elements: E & Validate<CommandZero<N>, E>): Materialize<Fold<CommandZero<N>, Normalize<E>>>
command
,
function name<N extends string>(name: N): Definition<N>
name
,
function parse<const R extends AnyRoute>(route: R, input: Input): Parse<R>
parse
} from "@bomb.sh/router";
const
const app: Route<"gh", "help" | "execute", [Done<{}, []>]>
app
=
command<"gh", readonly []>(start: Definition<"gh">): Route<"gh", "help" | "execute", [Done<{}, []>]>
command
(
name<"gh">(name: "gh"): Definition<"gh">
name
("gh"));
const
const result: Parse<Route<"gh", "help" | "execute", [Done<{}, []>]>>
result
=
parse<Route<"gh", "help" | "execute", [Done<{}, []>]>>(route: Route<"gh", "help" | "execute", [Done<{}, []>]>, input: Input): Parse<Route<"gh", "help" | "execute", [...]>>
parse
(
const app: Route<"gh", "help" | "execute", [Done<{}, []>]>
app
, {
argv: string[]
argv
:
var process: NodeJS.Process
process
.
NodeJS.Process.argv: string[]

The process.argv property returns an array containing the command-line arguments passed when the Node.js process was launched. The first element will be

execPath

. See process.argv0 if access to the original value of argv[0] is needed. The second element will be the path to the JavaScript file being executed. The remaining elements will be any additional command-line arguments.

For example, assuming the following script for process-args.js:

import { argv } from 'node:process';
// print process.argv
argv.forEach((val, index) => {
console.log(`${index}: ${val}`);
});

Launching the Node.js process as:

Terminal window
node process-args.js one two=three four

Would generate the output:

0: /usr/local/bin/node
1: /Users/mjr/work/node/process-args.js
2: one
3: two=three
4: four

@since ― v0.1.27

argv
.
Array<string>.slice(start?: number, end?: number): string[]

Returns a copy of a section of an array. For both start and end, a negative index can be used to indicate an offset from the end of the array. For example, -2 refers to the second to last element of the array.

@param ― start The beginning index of the specified portion of the array. If start is undefined, then the slice begins at index 0.

@param ― end The end index of the specified portion of the array. This is exclusive of the element at the index 'end'. If end is undefined, then the slice extends to the end of the array.

slice
(2) });
if (!
const result: Parse<Route<"gh", "help" | "execute", [Done<{}, []>]>>
result
.
ok: boolean
ok
&&
const result: MethodNotAllowed | UnprocessableContent
result
.
Failure<C extends Status>.code: "method-not-allowed" | "unprocessable-content"
code
=== "unprocessable-content") {
for (const
const issue: StandardSchemaV1.Issue
issue
of
const result: UnprocessableContent
result
.
UnprocessableContent.issues: StandardSchemaV1.Issue[]
issues
) {
const
const key: string | undefined
key
=
const issue: StandardSchemaV1.Issue
issue
.
StandardSchemaV1<Input = unknown, Output = Input>.Issue.path?: readonly (PropertyKey | StandardSchemaV1.PathSegment)[] | undefined

The path of the issue, if any.

path
?.
ReadonlyArray<PropertyKey | StandardSchemaV1<Input = unknown, Output = Input>.PathSegment>.map<U>(callbackfn: (value: PropertyKey | StandardSchemaV1<Input = unknown, Output = Input>.PathSegment, index: number, array: readonly (PropertyKey | StandardSchemaV1.PathSegment)[]) => U, thisArg?: any): U[]

Calls a defined callback function on each element of an array, and returns an array that contains the results.

@param ― callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.

@param ― thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.

map
((
p: PropertyKey | StandardSchemaV1.PathSegment
p
) => (typeof
p: PropertyKey | StandardSchemaV1.PathSegment
p
=== "object" ?
p: StandardSchemaV1.PathSegment
p
.
StandardSchemaV1<Input = unknown, Output = Input>.PathSegment.key: PropertyKey

The key representing a path segment.

key
:
p: PropertyKey
p
))
.
Array<PropertyKey>.join(separator?: string): string

Adds all the elements of an array into a string, separated by the specified separator string.

@param ― separator A string used to separate one element of the array from the next in the resulting string. If omitted, the array elements are separated with a comma.

join
(".");
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 and process.stderr. 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 for more information.

Example using the global console:

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:

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

@see ― source

console
.
Console.error(message?: any, ...optionalParams: any[]): void

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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@since ― v0.1.100

error
(
const key: string | undefined
key
? `${
const key: string
key
}: ${
const issue: StandardSchemaV1.Issue
issue
.
StandardSchemaV1<Input = unknown, Output = Input>.Issue.message: string

The error message of the issue.

message
}` :
const issue: StandardSchemaV1.Issue
issue
.
StandardSchemaV1<Input = unknown, Output = Input>.Issue.message: string

The error message of the issue.

message
);
}
var process: NodeJS.Process
process
.
NodeJS.Process.exit(code?: number | string | null): 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:

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:

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:

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.

@since ― v0.1.13

@param ― code The exit code. For string type, only integer strings (e.g.,'1') are allowed.

exit
(1);
}