diff --git a/doc/api/errors.md b/doc/api/errors.md index aef6580822859e..99f398f15f4998 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -568,22 +568,51 @@ found [here][online]. Used generically to identify that an iterable argument (i.e. a value that works with `for...of` loops) is required, but not provided to a Node.js API. + +### ERR_ASSERTION + +Used as special type of error that can be triggered whenever Node.js detects an +exceptional logic violation that should never occur. These are raised typically +by the `assert` module. + ### ERR_CONSOLE_WRITABLE_STREAM Used when `Console` is instantiated without `stdout` stream or when `stdout` or `stderr` streams are not writable. + +### ERR_CPU_USAGE + +Used when the native call from `process.cpuUsage` cannot be processed properly. + ### ERR_FALSY_VALUE_REJECTION The `ERR_FALSY_VALUE_REJECTION` error code is used by the `util.callbackify()` API when a callbackified `Promise` is rejected with a falsy value (e.g. `null`). + +### ERR_HTTP_HEADERS_SENT + +Used when headers have already been sent and another attempt is made to add +more headers. + + +### ERR_HTTP_INVALID_STATUS_CODE + +Used for status codes outside the regular status code ranges (100-999). + + +### ERR_HTTP_TRAILER_INVALID + +Used when the `Trailer` header is set even though the transfer encoding does not +support that. + ### ERR_INDEX_OUT_OF_RANGE -Used when a given index is out of the accepted range. +Used when a given index is out of the accepted range (e.g. negative offsets). ### ERR_INVALID_ARG_TYPE @@ -591,18 +620,33 @@ Used when a given index is out of the accepted range. Used generically to identify that an argument of the wrong type has been passed to a Node.js API. + +### ERR_INVALID_ARRAY_LENGTH + +Used when an Array is not of the expected length or in a valid range. + ### ERR_INVALID_CALLBACK Used generically to identify that a callback function is required and has not been provided to a Node.js API. + +### ERR_INVALID_CHAR + +Used when invalid characters are detected in headers. + ### ERR_INVALID_CURSOR_POS The `'ERR_INVALID_CURSOR_POS'` is thrown specifically when a cursor on a given stream is attempted to move to a specified row without a specified column. + +### ERR_INVALID_FD + +Used when a file descriptor ('fd') is not valid (e.g. it has a negative value). + ### ERR_INVALID_FILE_URL_HOST @@ -638,6 +682,12 @@ passed in an options object. Used when both `breakEvalOnSigint` and `eval` options are set in the REPL config, which is not supported. + +### ERR_INVALID_REPL_HISTORY + +Used in the `repl` in case the old history file is used and an error occurred +while trying to read and parse it. + ### ERR_INVALID_SYNC_FORK_INPUT @@ -716,14 +766,33 @@ synchronous forked Node.js process. See the documentation for the ### ERR_MISSING_ARGS -Used when a required argument of a Node.js API is not passed. This is currently -only used in the [WHATWG URL API][] for strict compliance with the specification -(which in some cases may accept `func(undefined)` but not `func()`). In most -native Node.js APIs, `func(undefined)` and `func()` are treated identically, and -the [`ERR_INVALID_ARG_TYPE`][] error code may be used instead. +Used when a required argument of a Node.js API is not passed. This is only used +for strict compliance with the API specification (which in some cases may accept +`func(undefined)` but not `func()`). In most native Node.js APIs, +`func(undefined)` and `func()` are treated identically, and the +[`ERR_INVALID_ARG_TYPE`][] error code may be used instead. + + +### ERR_MULTIPLE_CALLBACK + +Used when a callback is called more then once. + +*Note*: A callback is almost always meant to only be called once as the query +can either be fulfilled or rejected but not both at the same time. The latter +would be possible by calling a callback more then once. + + +### ERR_NO_CRYPTO + +Used when an attempt is made to use crypto features while Node.js is not +compiled with OpenSSL crypto support. + + +### ERR_PARSE_HISTORY_DATA ### ERR_SOCKET_ALREADY_BOUND + Used when an attempt is made to bind a socket that has already been bound. @@ -748,12 +817,6 @@ Used when data cannot be sent on a socket. Used when a call is made and the UDP subsystem is not running. - -### ERR_NO_CRYPTO - -Used when an attempt is made to use crypto features while Node.js is not -compiled with OpenSSL crypto support. - ### ERR_STDERR_CLOSE @@ -766,6 +829,19 @@ Node.js does not allow `stdout` or `stderr` Streams to be closed by user code. Used when an attempt is made to close the `process.stdout` stream. By design, Node.js does not allow `stdout` or `stderr` Streams to be closed by user code. + +### ERR_STREAM_HAS_STRINGDECODER + +Used to prevent an abort if a string decoder was set on the Socket. + +Example +```js +const Socket = require('net').Socket; +const instance = new Socket(); + +instance.setEncoding('utf-8'); +``` + ### ERR_UNKNOWN_BUILTIN_MODULE @@ -795,6 +871,11 @@ Used when an attempt is made to launch a Node.js process with an unknown by errors in user code, although it is not impossible. Occurrences of this error are most likely an indication of a bug within Node.js itself. + +### ERR_V8BREAKITERATOR + +Used when the V8 BreakIterator API is used but the full ICU data set is not +installed. [`ERR_INVALID_ARG_TYPE`]: #ERR_INVALID_ARG_TYPE [`child.kill()`]: child_process.html#child_process_child_kill_signal @@ -817,6 +898,7 @@ are most likely an indication of a bug within Node.js itself. [domains]: domain.html [event emitter-based]: events.html#events_class_eventemitter [file descriptors]: https://en.wikipedia.org/wiki/File_descriptor +[intl wiki]: https://github.com/nodejs/node/wiki/Intl [online]: http://man7.org/linux/man-pages/man3/errno.3.html [stream-based]: stream.html [syscall]: http://man7.org/linux/man-pages/man2/syscall.2.html diff --git a/lib/_http_server.js b/lib/_http_server.js index c3a10112ff2887..34e7b6d29c2cae 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -213,10 +213,8 @@ function writeHead(statusCode, reason, obj) { if (k) this.setHeader(k, obj[k]); } } - if (k === undefined) { - if (this._header) { - throw new errors.Error('ERR_HTTP_HEADERS_SENT'); - } + if (k === undefined && this._header) { + throw new errors.Error('ERR_HTTP_HEADERS_SENT'); } // only progressive api is used headers = this[outHeadersKey]; @@ -225,10 +223,8 @@ function writeHead(statusCode, reason, obj) { headers = obj; } - if (common._checkInvalidHeaderChar(this.statusMessage)) { - throw new errors.Error('ERR_HTTP_INVALID_CHAR', - 'Invalid character in statusMessage.'); - } + if (common._checkInvalidHeaderChar(this.statusMessage)) + throw new errors.Error('ERR_INVALID_CHAR', 'statusMessage'); var statusLine = 'HTTP/1.1 ' + statusCode + ' ' + this.statusMessage + CRLF; diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js index 0f607a6da38593..34a83f76322807 100644 --- a/lib/_stream_transform.js +++ b/lib/_stream_transform.js @@ -77,8 +77,7 @@ function afterTransform(er, data) { var cb = ts.writecb; if (!cb) { - return this.emit('error', - new errors.Error('ERR_TRANSFORM_MULTIPLE_CALLBACK')); + return this.emit('error', new errors.Error('ERR_MULTIPLE_CALLBACK')); } ts.writechunk = null; @@ -207,6 +206,7 @@ function done(stream, er, data) { if (data != null) // single equals check for both `null` and `undefined` stream.push(data); + // TODO(BridgeAR): Write a test for these two error cases // if there's nothing in the write buffer, then that means // that nothing more will ever be provided if (stream._writableState.length) diff --git a/lib/dgram.js b/lib/dgram.js index 55753b177279a9..3204ad87cd5cd9 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -79,7 +79,7 @@ function newHandle(type) { return handle; } - throw new errors.Error('ERR_SOCKET_BAD_TYPE'); + throw new errors.TypeError('ERR_SOCKET_BAD_TYPE'); } diff --git a/lib/internal/errors.js b/lib/internal/errors.js index f1835516a70e95..109892f831247d 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -110,32 +110,32 @@ module.exports = exports = { // // Note: Please try to keep these in alphabetical order E('ERR_ARG_NOT_ITERABLE', '%s must be iterable'); -E('ERR_ASSERTION', (msg) => msg); +E('ERR_ASSERTION', '%s'); E('ERR_CONSOLE_WRITABLE_STREAM', - (name) => `Console expects a writable stream instance for ${name}`); -E('ERR_CPU_USAGE', (errMsg) => `Unable to obtain cpu usage ${errMsg}`); + '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', 'Cannot render headers after they are sent to the client'); -E('ERR_HTTP_INVALID_CHAR', 'Invalid character in statusMessage.'); -E('ERR_HTTP_INVALID_STATUS_CODE', - (originalStatusCode) => `Invalid status code: ${originalStatusCode}`); +E('ERR_HTTP_INVALID_STATUS_CODE', 'Invalid status code: %s'); +E('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', (name, length, actual) => { - let msg = `The "${name}" array must have a length of ${length}`; - if (arguments.length > 2) { - const len = Array.isArray(actual) ? actual.length : actual; - msg += `. Received length ${len}`; - } - return msg; + const assert = lazyAssert(); + assert.strictEqual(typeof actual, 'number'); + return `The "${name}" array must have a length of ${ + length}. Received length ${actual}`; }); -E('ERR_INVALID_ARG_TYPE', invalidArgType); -E('ERR_INVALID_CALLBACK', 'callback must be a function'); -E('ERR_INVALID_FD', (fd) => `"fd" must be a positive integer: ${fd}`); +E('ERR_INVALID_CALLBACK', 'Callback must be a function'); +E('ERR_INVALID_CHAR', 'Invalid character in %s'); E('ERR_INVALID_CURSOR_POS', 'Cannot set cursor row without setting its column'); -E('ERR_INVALID_FILE_URL_HOST', 'File URL host %s'); +E('ERR_INVALID_FD', '"fd" must be a positive integer: %s'); +E('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', @@ -144,47 +144,42 @@ E('ERR_INVALID_OPT_VALUE', }); E('ERR_INVALID_REPL_EVAL_CONFIG', 'Cannot specify both "breakEvalOnSigint" and "eval" for REPL'); +E('ERR_INVALID_REPL_HISTORY', 'Expected array, got %s'); E('ERR_INVALID_SYNC_FORK_INPUT', - (value) => { - return 'Asynchronous forks do not support Buffer, Uint8Array or string' + - `input: ${value}`; - }); + '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', - (expected) => `The URL must be ${oneOf(expected, 'scheme')}`); -E('ERR_INVALID_REPL_HISTORY', - (repl_history) => `Expected array, got ${repl_history}`); -E('ERR_IPC_CHANNEL_CLOSED', 'channel closed'); + (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_PARSE_HISTORY_DATA', - (oldHistoryPath) => `Could not parse history data in ${oldHistoryPath}`); +E('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times'); E('ERR_NO_CRYPTO', 'Node.js is not compiled with OpenSSL crypto support'); +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', + '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_HAS_STRINGDECODER', 'Stream has StringDecoder'); E('ERR_TRANSFORM_ALREADY_TRANSFORMING', 'Calling transform done when still transforming'); -E('ERR_TRANSFORM_MULTIPLE_CALLBACK', 'Callback called multiple times'); E('ERR_TRANSFORM_WITH_LENGTH_0', - 'Calling transform done when ws.length != 0'); -E('ERR_HTTP_TRAILER_INVALID', - 'Trailers are invalid with this transfer encoding'); -E('ERR_UNKNOWN_BUILTIN_MODULE', (id) => `No such built-in module: ${id}`); -E('ERR_UNKNOWN_SIGNAL', (signal) => `Unknown signal: ${signal}`); + 'Calling transform done when writableState.length != 0'); +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_SOCKET_ALREADY_BOUND', 'Socket is already bound'); -E('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_V8BREAKITERATOR', 'full ICU data not installed. ' + +E('ERR_V8BREAKITERATOR', 'Full ICU data not installed. ' + 'See https://github.com/nodejs/node/wiki/Intl'); // Add new errors from here... @@ -200,6 +195,7 @@ function invalidArgType(name, expected, actual) { } function missingArgs(...args) { + const assert = lazyAssert(); assert(args.length > 0, 'At least one arg needs to be specified'); let msg = 'The '; const len = args.length; diff --git a/lib/internal/process.js b/lib/internal/process.js index 1636e73b7e009d..bb9117ea09de50 100644 --- a/lib/internal/process.js +++ b/lib/internal/process.js @@ -86,7 +86,7 @@ function setup_hrtime() { } if (time.length !== 2) { throw new errors.TypeError('ERR_INVALID_ARRAY_LENGTH', 'time', 2, - time); + time.length); } const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - time[0]; @@ -181,7 +181,7 @@ function setupKillAndExit() { if (lazyConstants()[sig]) { err = process._kill(pid, lazyConstants()[sig]); } else { - throw new errors.Error('ERR_UNKNOWN_SIGNAL', `${sig}`); + throw new errors.TypeError('ERR_UNKNOWN_SIGNAL', sig); } } diff --git a/lib/internal/url.js b/lib/internal/url.js index 7d7c79149a5c4f..64ebf383e6eb31 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -1352,8 +1352,7 @@ function getPathFromURLWin32(url) { function getPathFromURLPosix(url) { if (url.hostname !== '') { - return new errors.TypeError('ERR_INVALID_FILE_URL_HOST', - `must be "localhost" or empty on ${platform}`); + return new errors.TypeError('ERR_INVALID_FILE_URL_HOST', platform); } var pathname = url.pathname; for (var n = 0; n < pathname.length; n++) { diff --git a/lib/internal/util.js b/lib/internal/util.js index efdd7e0fd277b3..543ebbaf6d6fa6 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -180,7 +180,7 @@ function convertToValidSignal(signal) { if (signalName) return signalName; } - throw new errors.Error('ERR_UNKNOWN_SIGNAL', signal); + throw new errors.TypeError('ERR_UNKNOWN_SIGNAL', signal); } function getConstructorOf(obj) { diff --git a/lib/v8.js b/lib/v8.js index ba95c98dadc1ee..fccc39edc6833f 100644 --- a/lib/v8.js +++ b/lib/v8.js @@ -154,7 +154,7 @@ class DefaultSerializer extends Serializer { i = arrayBufferViewTypeToIndex.get(tag); if (i === undefined) { - throw this._getDataCloneError(`Unknown host object type: ${tag}`); + throw new this._getDataCloneError(`Unknown host object type: ${tag}`); } } this.writeUint32(i); diff --git a/test/parallel/test-child-process-constructor.js b/test/parallel/test-child-process-constructor.js index 8e62f5cc238c22..54052d9f7140dd 100644 --- a/test/parallel/test-child-process-constructor.js +++ b/test/parallel/test-child-process-constructor.js @@ -68,6 +68,6 @@ assert(Number.isInteger(child.pid)); // try killing with invalid signal assert.throws(() => { child.kill('foo'); -}, common.expectsError({ code: 'ERR_UNKNOWN_SIGNAL' })); +}, common.expectsError({ code: 'ERR_UNKNOWN_SIGNAL', type: TypeError })); assert.strictEqual(child.kill(), true); diff --git a/test/parallel/test-child-process-fork-regr-gh-2847.js b/test/parallel/test-child-process-fork-regr-gh-2847.js index 08f7977459bae4..9e4412d1f73738 100644 --- a/test/parallel/test-child-process-fork-regr-gh-2847.js +++ b/test/parallel/test-child-process-fork-regr-gh-2847.js @@ -60,11 +60,8 @@ const server = net.createServer(function(s) { send(function(err) { // Ignore errors when sending the second handle because the worker // may already have exited. - if (err) { - if ((err.message !== 'channel closed') && - (err.code !== 'ECONNREFUSED')) { - throw err; - } + if (err && err.message !== 'Channel closed') { + throw err; } }); }); diff --git a/test/parallel/test-child-process-send-after-close.js b/test/parallel/test-child-process-send-after-close.js index 78cf3b6697ea1f..5039767aeb7660 100644 --- a/test/parallel/test-child-process-send-after-close.js +++ b/test/parallel/test-child-process-send-after-close.js @@ -10,9 +10,11 @@ child.on('close', common.mustCall((code, signal) => { assert.strictEqual(code, 0); assert.strictEqual(signal, null); - function testError(err) { - assert.strictEqual(err.message, 'channel closed'); - } + const testError = common.expectsError({ + type: Error, + message: 'Channel closed', + code: 'ERR_IPC_CHANNEL_CLOSED' + }); child.on('error', common.mustCall(testError)); diff --git a/test/parallel/test-child-process-spawnsync-kill-signal.js b/test/parallel/test-child-process-spawnsync-kill-signal.js index f199d288a1ab0c..90d6225223e635 100644 --- a/test/parallel/test-child-process-spawnsync-kill-signal.js +++ b/test/parallel/test-child-process-spawnsync-kill-signal.js @@ -31,7 +31,7 @@ if (process.argv[2] === 'child') { // Verify that an error is thrown for unknown signals. assert.throws(() => { spawn('SIG_NOT_A_REAL_SIGNAL'); - }, common.expectsError({ code: 'ERR_UNKNOWN_SIGNAL' })); + }, common.expectsError({ code: 'ERR_UNKNOWN_SIGNAL', type: TypeError })); // Verify that the default kill signal is SIGTERM. { diff --git a/test/parallel/test-child-process-spawnsync-validation-errors.js b/test/parallel/test-child-process-spawnsync-validation-errors.js index dab4b1d37d80f9..98a947825f297b 100644 --- a/test/parallel/test-child-process-spawnsync-validation-errors.js +++ b/test/parallel/test-child-process-spawnsync-validation-errors.js @@ -186,7 +186,7 @@ if (!common.isWindows) { // Validate the killSignal option const typeErr = /^TypeError: "killSignal" must be a string or number$/; const unknownSignalErr = - common.expectsError({ code: 'ERR_UNKNOWN_SIGNAL' }); + common.expectsError({ code: 'ERR_UNKNOWN_SIGNAL', type: TypeError }); pass('killSignal', undefined); pass('killSignal', null); diff --git a/test/parallel/test-dgram-createSocket-type.js b/test/parallel/test-dgram-createSocket-type.js index 125a9d0be5cc1c..96e3d6c8673d16 100644 --- a/test/parallel/test-dgram-createSocket-type.js +++ b/test/parallel/test-dgram-createSocket-type.js @@ -27,7 +27,7 @@ invalidTypes.forEach((invalidType) => { dgram.createSocket(invalidType); }, common.expectsError({ code: 'ERR_SOCKET_BAD_TYPE', - type: Error, + type: TypeError, message: errMessage })); }); diff --git a/test/parallel/test-process-kill-pid.js b/test/parallel/test-process-kill-pid.js index bf6f552fb07f04..74491710d2646b 100644 --- a/test/parallel/test-process-kill-pid.js +++ b/test/parallel/test-process-kill-pid.js @@ -60,7 +60,7 @@ assert.throws(function() { process.kill(-1 / 0); }, // Test that kill throws an error for invalid signal const unknownSignal = common.expectsError({ code: 'ERR_UNKNOWN_SIGNAL', - type: Error, + type: TypeError, message: 'Unknown signal: test' }); diff --git a/test/parallel/test-process-next-tick.js b/test/parallel/test-process-next-tick.js index 9cbdfc6d3b6a2d..5c078870806cc5 100644 --- a/test/parallel/test-process-next-tick.js +++ b/test/parallel/test-process-next-tick.js @@ -43,6 +43,6 @@ process.on('exit', function() { common.expectsError({ code: 'ERR_INVALID_CALLBACK', type: TypeError, - message: 'callback must be a function' + message: 'Callback must be a function' })); }); diff --git a/test/parallel/test-stream-transform-callback-twice.js b/test/parallel/test-stream-transform-callback-twice.js index afb55faa1a27c1..83c799b92fba25 100644 --- a/test/parallel/test-stream-transform-callback-twice.js +++ b/test/parallel/test-stream-transform-callback-twice.js @@ -1,15 +1,14 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); const { Transform } = require('stream'); const stream = new Transform({ transform(chunk, enc, cb) { cb(); cb(); } }); -stream.on('error', common.mustCall((err) => { - assert.strictEqual(err.toString(), - 'Error [ERR_TRANSFORM_MULTIPLE_CALLBACK]: ' + - 'Callback called multiple times'); +stream.on('error', common.expectsError({ + type: Error, + message: 'Callback called multiple times', + code: 'ERR_MULTIPLE_CALLBACK' })); stream.write('foo');