Browse Source

errors: fix and improve error types

1) Add missing lazy assert call
2) Remove obsolete error type
3) Name undocumented error type more appropriate
4) Consolidate error type style (rely on util.format
   instead of using a function)
5) Uppercase the first letter from error messages
6) Improve some internal error parameters

PR-URL: https://github.com/nodejs/node/pull/13857
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
v6
Ruben Bridgewater 8 years ago
committed by Tobias Nießen
parent
commit
1698c8e165
  1. 6
      lib/_http_server.js
  2. 4
      lib/_stream_transform.js
  3. 74
      lib/internal/errors.js
  4. 2
      lib/internal/process.js
  5. 3
      lib/internal/url.js
  6. 7
      test/parallel/test-child-process-fork-regr-gh-2847.js
  7. 8
      test/parallel/test-child-process-send-after-close.js
  8. 2
      test/parallel/test-process-next-tick.js
  9. 9
      test/parallel/test-stream-transform-callback-twice.js

6
lib/_http_server.js

@ -225,10 +225,8 @@ function writeHead(statusCode, reason, obj) {
headers = obj; headers = obj;
} }
if (common._checkInvalidHeaderChar(this.statusMessage)) { if (common._checkInvalidHeaderChar(this.statusMessage))
throw new errors.Error('ERR_HTTP_INVALID_CHAR', throw new errors.Error('ERR_INVALID_CHAR', 'statusMessage');
'Invalid character in statusMessage.');
}
var statusLine = 'HTTP/1.1 ' + statusCode + ' ' + this.statusMessage + CRLF; var statusLine = 'HTTP/1.1 ' + statusCode + ' ' + this.statusMessage + CRLF;

4
lib/_stream_transform.js

@ -77,8 +77,7 @@ function afterTransform(er, data) {
var cb = ts.writecb; var cb = ts.writecb;
if (!cb) { if (!cb) {
return this.emit('error', return this.emit('error', new errors.Error('ERR_MULTIPLE_CALLBACK'));
new errors.Error('ERR_TRANSFORM_MULTIPLE_CALLBACK'));
} }
ts.writechunk = null; ts.writechunk = null;
@ -207,6 +206,7 @@ function done(stream, er, data) {
if (data != null) // single equals check for both `null` and `undefined` if (data != null) // single equals check for both `null` and `undefined`
stream.push(data); stream.push(data);
// TODO(BridgeAR): Write a test for these two error cases
// if there's nothing in the write buffer, then that means // if there's nothing in the write buffer, then that means
// that nothing more will ever be provided // that nothing more will ever be provided
if (stream._writableState.length) if (stream._writableState.length)

74
lib/internal/errors.js

@ -110,32 +110,32 @@ module.exports = exports = {
// //
// Note: Please try to keep these in alphabetical order // Note: Please try to keep these in alphabetical order
E('ERR_ARG_NOT_ITERABLE', '%s must be iterable'); E('ERR_ARG_NOT_ITERABLE', '%s must be iterable');
E('ERR_ASSERTION', (msg) => msg); E('ERR_ASSERTION', '%s');
E('ERR_CONSOLE_WRITABLE_STREAM', E('ERR_CONSOLE_WRITABLE_STREAM',
(name) => `Console expects a writable stream instance for ${name}`); 'Console expects a writable stream instance for %s');
E('ERR_CPU_USAGE', (errMsg) => `Unable to obtain cpu usage ${errMsg}`); E('ERR_CPU_USAGE', 'Unable to obtain cpu usage %s');
E('ERR_FALSY_VALUE_REJECTION', 'Promise was rejected with falsy value'); E('ERR_FALSY_VALUE_REJECTION', 'Promise was rejected with falsy value');
E('ERR_HTTP_HEADERS_SENT', E('ERR_HTTP_HEADERS_SENT',
'Cannot render headers after they are sent to the client'); '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', 'Invalid status code: %s');
E('ERR_HTTP_INVALID_STATUS_CODE', E('ERR_HTTP_TRAILER_INVALID',
(originalStatusCode) => `Invalid status code: ${originalStatusCode}`); 'Trailers are invalid with this transfer encoding');
E('ERR_INDEX_OUT_OF_RANGE', 'Index out of range'); E('ERR_INDEX_OUT_OF_RANGE', 'Index out of range');
E('ERR_INVALID_ARG_TYPE', invalidArgType);
E('ERR_INVALID_ARRAY_LENGTH', E('ERR_INVALID_ARRAY_LENGTH',
(name, length, actual) => { (name, length, actual) => {
let msg = `The "${name}" array must have a length of ${length}`; const assert = lazyAssert();
if (arguments.length > 2) { assert.strictEqual(typeof actual, 'number');
const len = Array.isArray(actual) ? actual.length : actual; return `The "${name}" array must have a length of ${
msg += `. Received length ${len}`; length}. Received length ${actual}`;
}
return msg;
}); });
E('ERR_INVALID_ARG_TYPE', invalidArgType); E('ERR_INVALID_CALLBACK', 'Callback must be a function');
E('ERR_INVALID_CALLBACK', 'callback must be a function'); E('ERR_INVALID_CHAR', 'Invalid character in %s');
E('ERR_INVALID_FD', (fd) => `"fd" must be a positive integer: ${fd}`);
E('ERR_INVALID_CURSOR_POS', E('ERR_INVALID_CURSOR_POS',
'Cannot set cursor row without setting its column'); '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_FILE_URL_PATH', 'File URL path %s');
E('ERR_INVALID_HANDLE_TYPE', 'This handle type cannot be sent'); E('ERR_INVALID_HANDLE_TYPE', 'This handle type cannot be sent');
E('ERR_INVALID_OPT_VALUE', E('ERR_INVALID_OPT_VALUE',
@ -144,47 +144,42 @@ E('ERR_INVALID_OPT_VALUE',
}); });
E('ERR_INVALID_REPL_EVAL_CONFIG', E('ERR_INVALID_REPL_EVAL_CONFIG',
'Cannot specify both "breakEvalOnSigint" and "eval" for REPL'); 'Cannot specify both "breakEvalOnSigint" and "eval" for REPL');
E('ERR_INVALID_REPL_HISTORY', 'Expected array, got %s');
E('ERR_INVALID_SYNC_FORK_INPUT', E('ERR_INVALID_SYNC_FORK_INPUT',
(value) => { 'Asynchronous forks do not support Buffer, Uint8Array or string input: %s');
return 'Asynchronous forks do not support Buffer, Uint8Array or string' +
`input: ${value}`;
});
E('ERR_INVALID_THIS', 'Value of "this" must be of type %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_TUPLE', '%s must be an iterable %s tuple');
E('ERR_INVALID_URL', 'Invalid URL: %s'); E('ERR_INVALID_URL', 'Invalid URL: %s');
E('ERR_INVALID_URL_SCHEME', E('ERR_INVALID_URL_SCHEME',
(expected) => `The URL must be ${oneOf(expected, 'scheme')}`); (expected) => {
E('ERR_INVALID_REPL_HISTORY', lazyAssert();
(repl_history) => `Expected array, got ${repl_history}`); return `The URL must be ${oneOf(expected, 'scheme')}`;
E('ERR_IPC_CHANNEL_CLOSED', 'channel closed'); });
E('ERR_IPC_CHANNEL_CLOSED', 'Channel closed');
E('ERR_IPC_DISCONNECTED', 'IPC channel is already disconnected'); 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_ONE_PIPE', 'Child process can have only one IPC pipe');
E('ERR_IPC_SYNC_FORK', 'IPC cannot be used with synchronous forks'); E('ERR_IPC_SYNC_FORK', 'IPC cannot be used with synchronous forks');
E('ERR_MISSING_ARGS', missingArgs); E('ERR_MISSING_ARGS', missingArgs);
E('ERR_PARSE_HISTORY_DATA', E('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times');
(oldHistoryPath) => `Could not parse history data in ${oldHistoryPath}`);
E('ERR_NO_CRYPTO', 'Node.js is not compiled with OpenSSL crypto support'); 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_STDERR_CLOSE', 'process.stderr cannot be closed');
E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed'); E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed');
E('ERR_STREAM_HAS_STRINGDECODER', 'Stream has StringDecoder'); E('ERR_STREAM_HAS_STRINGDECODER', 'Stream has StringDecoder');
E('ERR_TRANSFORM_ALREADY_TRANSFORMING', E('ERR_TRANSFORM_ALREADY_TRANSFORMING',
'Calling transform done when still transforming'); 'Calling transform done when still transforming');
E('ERR_TRANSFORM_MULTIPLE_CALLBACK', 'Callback called multiple times');
E('ERR_TRANSFORM_WITH_LENGTH_0', E('ERR_TRANSFORM_WITH_LENGTH_0',
'Calling transform done when ws.length != 0'); 'Calling transform done when writableState.length != 0');
E('ERR_HTTP_TRAILER_INVALID', E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s');
'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}`);
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type'); E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type');
E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type'); E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type');
E('ERR_SOCKET_ALREADY_BOUND', 'Socket is already bound'); E('ERR_V8BREAKITERATOR', 'Full ICU data not installed. ' +
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. ' +
'See https://github.com/nodejs/node/wiki/Intl'); 'See https://github.com/nodejs/node/wiki/Intl');
// Add new errors from here... // Add new errors from here...
@ -200,6 +195,7 @@ function invalidArgType(name, expected, actual) {
} }
function missingArgs(...args) { function missingArgs(...args) {
const assert = lazyAssert();
assert(args.length > 0, 'At least one arg needs to be specified'); assert(args.length > 0, 'At least one arg needs to be specified');
let msg = 'The '; let msg = 'The ';
const len = args.length; const len = args.length;

2
lib/internal/process.js

@ -86,7 +86,7 @@ function setup_hrtime() {
} }
if (time.length !== 2) { if (time.length !== 2) {
throw new errors.TypeError('ERR_INVALID_ARRAY_LENGTH', 'time', 2, throw new errors.TypeError('ERR_INVALID_ARRAY_LENGTH', 'time', 2,
time); time.length);
} }
const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - time[0]; const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - time[0];

3
lib/internal/url.js

@ -1352,8 +1352,7 @@ function getPathFromURLWin32(url) {
function getPathFromURLPosix(url) { function getPathFromURLPosix(url) {
if (url.hostname !== '') { if (url.hostname !== '') {
return new errors.TypeError('ERR_INVALID_FILE_URL_HOST', return new errors.TypeError('ERR_INVALID_FILE_URL_HOST', platform);
`must be "localhost" or empty on ${platform}`);
} }
var pathname = url.pathname; var pathname = url.pathname;
for (var n = 0; n < pathname.length; n++) { for (var n = 0; n < pathname.length; n++) {

7
test/parallel/test-child-process-fork-regr-gh-2847.js

@ -60,11 +60,8 @@ const server = net.createServer(function(s) {
send(function(err) { send(function(err) {
// Ignore errors when sending the second handle because the worker // Ignore errors when sending the second handle because the worker
// may already have exited. // may already have exited.
if (err) { if (err && err.message !== 'Channel closed') {
if ((err.message !== 'channel closed') && throw err;
(err.code !== 'ECONNREFUSED')) {
throw err;
}
} }
}); });
}); });

8
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(code, 0);
assert.strictEqual(signal, null); assert.strictEqual(signal, null);
function testError(err) { const testError = common.expectsError({
assert.strictEqual(err.message, 'channel closed'); type: Error,
} message: 'Channel closed',
code: 'ERR_IPC_CHANNEL_CLOSED'
});
child.on('error', common.mustCall(testError)); child.on('error', common.mustCall(testError));

2
test/parallel/test-process-next-tick.js

@ -43,6 +43,6 @@ process.on('exit', function() {
common.expectsError({ common.expectsError({
code: 'ERR_INVALID_CALLBACK', code: 'ERR_INVALID_CALLBACK',
type: TypeError, type: TypeError,
message: 'callback must be a function' message: 'Callback must be a function'
})); }));
}); });

9
test/parallel/test-stream-transform-callback-twice.js

@ -1,15 +1,14 @@
'use strict'; 'use strict';
const common = require('../common'); const common = require('../common');
const assert = require('assert');
const { Transform } = require('stream'); const { Transform } = require('stream');
const stream = new Transform({ const stream = new Transform({
transform(chunk, enc, cb) { cb(); cb(); } transform(chunk, enc, cb) { cb(); cb(); }
}); });
stream.on('error', common.mustCall((err) => { stream.on('error', common.expectsError({
assert.strictEqual(err.toString(), type: Error,
'Error [ERR_TRANSFORM_MULTIPLE_CALLBACK]: ' + message: 'Callback called multiple times',
'Callback called multiple times'); code: 'ERR_MULTIPLE_CALLBACK'
})); }));
stream.write('foo'); stream.write('foo');

Loading…
Cancel
Save