Skip to content

errors: move error codes into separate module #14250

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions doc/guides/using-internal-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,22 @@ const err = new errors.TypeError('FOO', type);

## Adding new errors

New static error codes are added by modifying the `internal/errors.js` file
and appending the new error codes to the end using the utility `E()` method.
New static error codes are added by modifying the `internal/errors/codes.js` file.

```js
E('EXAMPLE_KEY1', 'This is the error value');
E('EXAMPLE_KEY2', (a, b) => `${a} ${b}`);
module.exports = {
// ...
EXAMPLE_KEY1: 'EXAMPLE_KEY1',
EXAMPLE_KEY2: 'EXAMPLE_KEY2',
// ...
};
```

And then appending the new error codes to the end in `internal/errors.js` using the utility `E()` method.

```js
E(codes.EXAMPLE_KEY1, 'This is the error value');
E(codes.EXAMPLE_KEY2, (a, b) => `${a} ${b}`);
```

The first argument passed to `E()` is the static identifier. The second
Expand Down
108 changes: 55 additions & 53 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// value statically and permanently identifies the error. While the error
// message may change, the code should not.

const codes = require('internal/errors/codes');
const kCode = Symbol('code');
const messages = new Map();

Expand Down Expand Up @@ -107,82 +108,83 @@ module.exports = exports = {
// Any error code added here should also be added to the documentation
//
// Note: Please try to keep these in alphabetical order
E('ERR_ARG_NOT_ITERABLE', '%s must be iterable');
E('ERR_ASSERTION', '%s');
E('ERR_BUFFER_OUT_OF_BOUNDS', bufferOutOfBounds);
E('ERR_CONSOLE_WRITABLE_STREAM',
E(codes.ERR_ARG_NOT_ITERABLE, '%s must be iterable');
E(codes.ERR_ASSERTION, '%s');
E(codes.ERR_BUFFER_OUT_OF_BOUNDS, bufferOutOfBounds);
E(codes.ERR_CONSOLE_WRITABLE_STREAM,
'Console expects a writable stream instance for %s');
E('ERR_CPU_USAGE', 'Unable to obtain cpu usage %s');
E('ERR_FALSY_VALUE_REJECTION', 'Promise was rejected with falsy value');
E('ERR_HTTP_HEADERS_SENT',
E(codes.ERR_CPU_USAGE, 'Unable to obtain cpu usage %s');
E(codes.ERR_FALSY_VALUE_REJECTION, 'Promise was rejected with falsy value');
E(codes.ERR_HTTP_HEADERS_SENT,
'Cannot render headers after they are sent to the client');
E('ERR_HTTP_INVALID_STATUS_CODE', 'Invalid status code: %s');
E('ERR_HTTP_TRAILER_INVALID',
E(codes.ERR_HTTP_INVALID_STATUS_CODE, 'Invalid status code: %s');
E(codes.ERR_HTTP_TRAILER_INVALID,
'Trailers are invalid with this transfer encoding');
E('ERR_INDEX_OUT_OF_RANGE', 'Index out of range');
E('ERR_INVALID_ARG_TYPE', invalidArgType);
E('ERR_INVALID_ARRAY_LENGTH',
E(codes.ERR_INDEX_OUT_OF_RANGE, 'Index out of range');
E(codes.ERR_INVALID_ARG_TYPE, invalidArgType);
E(codes.ERR_INVALID_ARRAY_LENGTH,
(name, length, actual) => {
const assert = lazyAssert();
assert.strictEqual(typeof actual, 'number');
return `The "${name}" array must have a length of ${
length}. Received length ${actual}`;
});
E('ERR_INVALID_BUFFER_SIZE', 'Buffer size must be a multiple of %s');
E('ERR_INVALID_CALLBACK', 'Callback must be a function');
E('ERR_INVALID_CHAR', 'Invalid character in %s');
E('ERR_INVALID_CURSOR_POS',
E(codes.ERR_INVALID_BUFFER_SIZE, 'Buffer size must be a multiple of %s');
E(codes.ERR_INVALID_CALLBACK, 'Callback must be a function');
E(codes.ERR_INVALID_CHAR, 'Invalid character in %s');
E(codes.ERR_INVALID_CURSOR_POS,
'Cannot set cursor row without setting its column');
E('ERR_INVALID_FD', '"fd" must be a positive integer: %s');
E('ERR_INVALID_FILE_URL_HOST',
E(codes.ERR_INVALID_FD, '"fd" must be a positive integer: %s');
E(codes.ERR_INVALID_FILE_URL_HOST,
'File URL host must be "localhost" or empty on %s');
E('ERR_INVALID_FILE_URL_PATH', 'File URL path %s');
E('ERR_INVALID_HANDLE_TYPE', 'This handle type cannot be sent');
E('ERR_INVALID_OPT_VALUE',
E(codes.ERR_INVALID_FILE_URL_PATH, 'File URL path %s');
E(codes.ERR_INVALID_HANDLE_TYPE, 'This handle type cannot be sent');
E(codes.ERR_INVALID_OPT_VALUE,
(name, value) => {
return `The value "${String(value)}" is invalid for option "${name}"`;
});
E('ERR_INVALID_REPL_EVAL_CONFIG',
E(codes.ERR_INVALID_REPL_EVAL_CONFIG,
'Cannot specify both "breakEvalOnSigint" and "eval" for REPL');
E('ERR_INVALID_SYNC_FORK_INPUT',
E(codes.ERR_INVALID_SYNC_FORK_INPUT,
'Asynchronous forks do not support Buffer, Uint8Array or string input: %s');
E('ERR_INVALID_THIS', 'Value of "this" must be of type %s');
E('ERR_INVALID_TUPLE', '%s must be an iterable %s tuple');
E('ERR_INVALID_URL', 'Invalid URL: %s');
E('ERR_INVALID_URL_SCHEME',
E(codes.ERR_INVALID_THIS, 'Value of "this" must be of type %s');
E(codes.ERR_INVALID_TUPLE, '%s must be an iterable %s tuple');
E(codes.ERR_INVALID_URL, 'Invalid URL: %s');
E(codes.ERR_INVALID_URL_SCHEME,
(expected) => {
lazyAssert();
return `The URL must be ${oneOf(expected, 'scheme')}`;
});
E('ERR_IPC_CHANNEL_CLOSED', 'Channel closed');
E('ERR_IPC_DISCONNECTED', 'IPC channel is already disconnected');
E('ERR_IPC_ONE_PIPE', 'Child process can have only one IPC pipe');
E('ERR_IPC_SYNC_FORK', 'IPC cannot be used with synchronous forks');
E('ERR_MISSING_ARGS', missingArgs);
E('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times');
E('ERR_NAPI_CONS_FUNCTION', 'Constructor must be a function');
E('ERR_NAPI_CONS_PROTOTYPE_OBJECT', 'Constructor.prototype must be an object');
E('ERR_NO_CRYPTO', 'Node.js is not compiled with OpenSSL crypto support');
E('ERR_NO_LONGER_SUPPORTED', '%s is no longer supported');
E('ERR_PARSE_HISTORY_DATA', 'Could not parse history data in %s');
E('ERR_SOCKET_ALREADY_BOUND', 'Socket is already bound');
E('ERR_SOCKET_BAD_TYPE',
E(codes.ERR_IPC_CHANNEL_CLOSED, 'Channel closed');
E(codes.ERR_IPC_DISCONNECTED, 'IPC channel is already disconnected');
E(codes.ERR_IPC_ONE_PIPE, 'Child process can have only one IPC pipe');
E(codes.ERR_IPC_SYNC_FORK, 'IPC cannot be used with synchronous forks');
E(codes.ERR_MISSING_ARGS, missingArgs);
E(codes.ERR_MULTIPLE_CALLBACK, 'Callback called multiple times');
E(codes.ERR_NAPI_CONS_FUNCTION, 'Constructor must be a function');
E(codes.ERR_NAPI_CONS_PROTOTYPE_OBJECT,
'Constructor.prototype must be an object');
E(codes.ERR_NO_CRYPTO, 'Node.js is not compiled with OpenSSL crypto support');
E(codes.ERR_NO_LONGER_SUPPORTED, '%s is no longer supported');
E(codes.ERR_PARSE_HISTORY_DATA, 'Could not parse history data in %s');
E(codes.ERR_SOCKET_ALREADY_BOUND, 'Socket is already bound');
E(codes.ERR_SOCKET_BAD_TYPE,
'Bad socket type specified. Valid types are: udp4, udp6');
E('ERR_SOCKET_CANNOT_SEND', 'Unable to send data');
E('ERR_SOCKET_BAD_PORT', 'Port should be > 0 and < 65536');
E('ERR_SOCKET_DGRAM_NOT_RUNNING', 'Not running');
E('ERR_STDERR_CLOSE', 'process.stderr cannot be closed');
E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed');
E('ERR_STREAM_WRAP', 'Stream has StringDecoder set or is in objectMode');
E('ERR_TRANSFORM_ALREADY_TRANSFORMING',
E(codes.ERR_SOCKET_CANNOT_SEND, 'Unable to send data');
E(codes.ERR_SOCKET_BAD_PORT, 'Port should be > 0 and < 65536');
E(codes.ERR_SOCKET_DGRAM_NOT_RUNNING, 'Not running');
E(codes.ERR_STDERR_CLOSE, 'process.stderr cannot be closed');
E(codes.ERR_STDOUT_CLOSE, 'process.stdout cannot be closed');
E(codes.ERR_STREAM_WRAP, 'Stream has StringDecoder set or is in objectMode');
E(codes.ERR_TRANSFORM_ALREADY_TRANSFORMING,
'Calling transform done when still transforming');
E('ERR_TRANSFORM_WITH_LENGTH_0',
E(codes.ERR_TRANSFORM_WITH_LENGTH_0,
'Calling transform done when writableState.length != 0');
E('ERR_UNKNOWN_ENCODING', 'Unknown encoding: %s');
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s');
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type');
E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type');
E('ERR_V8BREAKITERATOR', 'Full ICU data not installed. ' +
E(codes.ERR_UNKNOWN_ENCODING, 'Unknown encoding: %s');
E(codes.ERR_UNKNOWN_SIGNAL, 'Unknown signal: %s');
E(codes.ERR_UNKNOWN_STDIN_TYPE, 'Unknown stdin file type');
E(codes.ERR_UNKNOWN_STREAM_TYPE, 'Unknown stream file type');
E(codes.ERR_V8BREAKITERATOR, 'Full ICU data not installed. ' +
'See https://github.com/nodejs/node/wiki/Intl');
// Add new errors from here...

Expand Down
57 changes: 57 additions & 0 deletions lib/internal/errors/codes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use strict';

module.exports = {
ERR_ARG_NOT_ITERABLE: 'ERR_ARG_NOT_ITERABLE',
ERR_ASSERTION: 'ERR_ASSERTION',
ERR_BUFFER_OUT_OF_BOUNDS: 'ERR_BUFFER_OUT_OF_BOUNDS',
ERR_CONSOLE_WRITABLE_STREAM: 'ERR_CONSOLE_WRITABLE_STREAM',
ERR_CPU_USAGE: 'ERR_CPU_USAGE',
ERR_FALSY_VALUE_REJECTION: 'ERR_FALSY_VALUE_REJECTION',
ERR_HTTP_HEADERS_SENT: 'ERR_HTTP_HEADERS_SENT',
ERR_HTTP_INVALID_STATUS_CODE: 'ERR_HTTP_INVALID_STATUS_CODE',
ERR_HTTP_TRAILER_INVALID: 'ERR_HTTP_TRAILER_INVALID',
ERR_INDEX_OUT_OF_RANGE: 'ERR_INDEX_OUT_OF_RANGE',
ERR_INVALID_ARG_TYPE: 'ERR_INVALID_ARG_TYPE',
ERR_INVALID_ARRAY_LENGTH: 'ERR_INVALID_ARRAY_LENGTH',
ERR_INVALID_BUFFER_SIZE: 'ERR_INVALID_BUFFER_SIZE',
ERR_INVALID_CALLBACK: 'ERR_INVALID_CALLBACK',
ERR_INVALID_CHAR: 'ERR_INVALID_CHAR',
ERR_INVALID_CURSOR_POS: 'ERR_INVALID_CURSOR_POS',
ERR_INVALID_FD: 'ERR_INVALID_FD',
ERR_INVALID_FILE_URL_HOST: 'ERR_INVALID_FILE_URL_HOST',
ERR_INVALID_FILE_URL_PATH: 'ERR_INVALID_FILE_URL_PATH',
ERR_INVALID_HANDLE_TYPE: 'ERR_INVALID_HANDLE_TYPE',
ERR_INVALID_OPT_VALUE: 'ERR_INVALID_OPT_VALUE',
ERR_INVALID_REPL_EVAL_CONFIG: 'ERR_INVALID_REPL_EVAL_CONFIG',
ERR_INVALID_SYNC_FORK_INPUT: 'ERR_INVALID_SYNC_FORK_INPUT',
ERR_INVALID_THIS: 'ERR_INVALID_THIS',
ERR_INVALID_TUPLE: 'ERR_INVALID_TUPLE',
ERR_INVALID_URL: 'ERR_INVALID_URL',
ERR_INVALID_URL_SCHEME: 'ERR_INVALID_URL_SCHEME',
ERR_IPC_CHANNEL_CLOSED: 'ERR_IPC_CHANNEL_CLOSED',
ERR_IPC_DISCONNECTED: 'ERR_IPC_DISCONNECTED',
ERR_IPC_ONE_PIPE: 'ERR_IPC_ONE_PIPE',
ERR_IPC_SYNC_FORK: 'ERR_IPC_SYNC_FORK',
ERR_MISSING_ARGS: 'ERR_MISSING_ARGS',
ERR_MULTIPLE_CALLBACK: 'ERR_MULTIPLE_CALLBACK',
ERR_NAPI_CONS_FUNCTION: 'ERR_NAPI_CONS_FUNCTION',
ERR_NAPI_CONS_PROTOTYPE_OBJECT: 'ERR_NAPI_CONS_PROTOTYPE_OBJECT',
ERR_NO_CRYPTO: 'ERR_NO_CRYPTO',
ERR_NO_LONGER_SUPPORTED: 'ERR_NO_LONGER_SUPPORTED',
ERR_PARSE_HISTORY_DATA: 'ERR_PARSE_HISTORY_DATA',
ERR_SOCKET_ALREADY_BOUND: 'ERR_SOCKET_ALREADY_BOUND',
ERR_SOCKET_BAD_TYPE: 'ERR_SOCKET_BAD_TYPE',
ERR_SOCKET_CANNOT_SEND: 'ERR_SOCKET_CANNOT_SEND',
ERR_SOCKET_BAD_PORT: 'ERR_SOCKET_BAD_PORT',
ERR_SOCKET_DGRAM_NOT_RUNNING: 'ERR_SOCKET_DGRAM_NOT_RUNNING',
ERR_STDERR_CLOSE: 'ERR_STDERR_CLOSE',
ERR_STDOUT_CLOSE: 'ERR_STDOUT_CLOSE',
ERR_STREAM_WRAP: 'ERR_STREAM_WRAP',
ERR_TRANSFORM_ALREADY_TRANSFORMING: 'ERR_TRANSFORM_ALREADY_TRANSFORMING',
ERR_TRANSFORM_WITH_LENGTH_0: 'ERR_TRANSFORM_WITH_LENGTH_0',
ERR_UNKNOWN_ENCODING: 'ERR_UNKNOWN_ENCODING',
ERR_UNKNOWN_SIGNAL: 'ERR_UNKNOWN_SIGNAL',
ERR_UNKNOWN_STDIN_TYPE: 'ERR_UNKNOWN_STDIN_TYPE',
ERR_UNKNOWN_STREAM_TYPE: 'ERR_UNKNOWN_STREAM_TYPE',
ERR_V8BREAKITERATOR: 'ERR_V8BREAKITERATOR'
};
1 change: 1 addition & 0 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
'lib/internal/cluster/utils.js',
'lib/internal/cluster/worker.js',
'lib/internal/errors.js',
'lib/internal/errors/codes.js',
'lib/internal/freelist.js',
'lib/internal/fs.js',
'lib/internal/http.js',
Expand Down