errors, process: port internal/process errors to internal/errors by jasnell · Pull Request #11294 · nodejs/node · GitHub
Skip to content
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
100 changes: 78 additions & 22 deletions doc/api/errors.md
28 changes: 28 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,32 @@ module.exports = exports = {
//
// Note: Please try to keep these in alphabetical order
E('ERR_ASSERTION', (msg) => msg);
E('ERR_INVALID_ARG_TYPE', invalidArgType);
E('ERR_INVALID_CALLBACK', 'callback must be a function');
E('ERR_STDERR_CLOSE', 'process.stderr cannot be closed');
E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed');
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type');
E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type');
// Add new errors from here...

function invalidArgType(name, expected, actual) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copying my comment from #11300:

If I read it correctly, this would print The "options" argument must be type Object. It looks better to me as The "options" argument must be of type Object

assert(name, 'name is required');
assert(expected, 'expected is required');
var msg = `The "${name}" argument must be `;
if (Array.isArray(expected)) {
var len = expected.length;
expected = expected.map((i) => String(i));
if (len > 1) {
msg += `one of type ${expected.slice(0, len - 1).join(', ')}, or ` +

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe break out the expected.slice().join() into a variable? It is getting a little hard to read imo.

expected[len - 1];
} else {
msg += `of type ${expected[0]}`;
}
} else {
msg += `of type ${String(expected)}`;
}
if (arguments.length >= 3) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With only the first three arguments being used, maybe make this if (arguments.length === 3) {?

Feel free to disregard

msg += `. Received type ${actual !== null ? typeof actual : 'null'}`;
}
return msg;
}
3 changes: 2 additions & 1 deletion lib/internal/process/next_tick.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ exports.setup = setupNextTick;

function setupNextTick() {
const promises = require('internal/process/promises');
const errors = require('internal/errors');
const emitPendingUnhandledRejections = promises.setup(scheduleMicrotasks);
var nextTickQueue = [];
var microtasksScheduled = false;
Expand Down Expand Up @@ -139,7 +140,7 @@ function setupNextTick() {

function nextTick(callback) {
if (typeof callback !== 'function')
throw new TypeError('callback is not a function');
throw new errors.TypeError('ERR_INVALID_CALLBACK');
// on the way out, don't bother. it won't get fired anyway.
if (process._exiting)
return;
Expand Down
24 changes: 19 additions & 5 deletions lib/internal/process/stdio.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@

exports.setup = setupStdio;

var errors;

function lazyErrors() {
if (!errors)
errors = require('internal/errors');
return errors;
}

function setupStdio() {
var stdin, stdout, stderr;
var stdin;
var stdout;
var stderr;

function getStdout() {
if (stdout) return stdout;
stdout = createWritableStdioStream(1);
stdout.destroy = stdout.destroySoon = function(er) {
er = er || new Error('process.stdout cannot be closed.');
const errors = lazyErrors();
er = er || new errors.Error('ERR_STDOUT_CLOSE');
stdout.emit('error', er);
};
if (stdout.isTTY) {
Expand All @@ -22,7 +33,8 @@ function setupStdio() {
if (stderr) return stderr;
stderr = createWritableStdioStream(2);
stderr.destroy = stderr.destroySoon = function(er) {
er = er || new Error('process.stderr cannot be closed.');
const errors = lazyErrors();
er = er || new errors.Error('ERR_STDERR_CLOSE');
stderr.emit('error', er);
};
if (stderr.isTTY) {
Expand Down Expand Up @@ -79,7 +91,8 @@ function setupStdio() {

default:
// Probably an error on in uv_guess_handle()
throw new Error('Implement me. Unknown stdin file type!');
const errors = lazyErrors();
throw new errors.Error('ERR_UNKNOWN_STDIN_TYPE');
}

// For supporting legacy API we put the FD here.
Expand Down Expand Up @@ -163,7 +176,8 @@ function createWritableStdioStream(fd) {

default:
// Probably an error on in uv_guess_handle()
throw new Error('Implement me. Unknown stream file type!');
const errors = lazyErrors();
throw new errors.Error('ERR_UNKNOWN_STREAM_TYPE');
}

// For supporting legacy API we put the FD here.
Expand Down
15 changes: 12 additions & 3 deletions lib/internal/process/warning.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@ const prefix = `(${process.release.name}:${process.pid}) `;

exports.setup = setupProcessWarnings;

var errors;
var fs;
var cachedFd;
var acquiringFd = false;
function nop() {}

function lazyErrors() {
if (!errors)
errors = require('internal/errors');
return errors;
}

function lazyFs() {
if (!fs)
fs = require('fs');
Expand Down Expand Up @@ -105,6 +112,7 @@ function setupProcessWarnings() {
// process.emitWarning(error)
// process.emitWarning(str[, type[, code]][, ctor])
process.emitWarning = function(warning, type, code, ctor) {
const errors = lazyErrors();
if (typeof type === 'function') {
ctor = type;
code = undefined;
Expand All @@ -115,17 +123,18 @@ function setupProcessWarnings() {
code = undefined;
}
if (code !== undefined && typeof code !== 'string')
throw new TypeError('\'code\' must be a String');
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'code', 'string');
if (type !== undefined && typeof type !== 'string')
throw new TypeError('\'type\' must be a String');
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'type', 'string');
if (warning === undefined || typeof warning === 'string') {
warning = new Error(warning);
warning.name = String(type || 'Warning');
if (code !== undefined) warning.code = code;
Error.captureStackTrace(warning, ctor || process.emitWarning);
}
if (!(warning instanceof Error)) {
throw new TypeError('\'warning\' must be an Error object or string.');
throw new errors.TypeError('ERR_INVALID_ARG_TYPE',
'warning', ['Error', 'string']);
}
if (warning.name === 'DeprecationWarning') {
if (process.noDeprecation)
Expand Down
20 changes: 20 additions & 0 deletions test/parallel/test-internal-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,23 @@ assert.throws(
() => errors.E('TEST_ERROR_USED_SYMBOL'),
/^AssertionError: Error symbol: TEST_ERROR_USED_SYMBOL was already used\.$/
);

// // Test ERR_INVALID_ARG_TYPE
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE', ['a', 'b']),
'The "a" argument must be of type b');
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE', ['a', ['b']]),
'The "a" argument must be of type b');
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE', ['a', ['b', 'c']]),
'The "a" argument must be one of type b, or c');
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE',
['a', ['b', 'c', 'd']]),
'The "a" argument must be one of type b, c, or d');
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE', ['a', 'b', 'c']),
'The "a" argument must be of type b. Received type string');
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE',
['a', 'b', undefined]),
'The "a" argument must be of type b. Received type ' +
'undefined');
assert.strictEqual(errors.message('ERR_INVALID_ARG_TYPE',
['a', 'b', null]),
'The "a" argument must be of type b. Received type null');
27 changes: 15 additions & 12 deletions test/parallel/test-process-emitwarning.js
Loading