Skip to content

Commit a14b252

Browse files
committed
errors: eliminate circular dependency on assert
PR-URL: #15002 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
1 parent 2e03138 commit a14b252

File tree

2 files changed

+42
-29
lines changed

2 files changed

+42
-29
lines changed

lib/internal/errors.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const kCode = Symbol('code');
1212
const messages = new Map();
1313

1414
// Lazily loaded
15-
var assert = null;
1615
var util = null;
1716

1817
function makeNodeError(Base) {
@@ -60,11 +59,22 @@ class AssertionError extends Error {
6059
}
6160
}
6261

62+
// This is defined here instead of using the assert module to avoid a
63+
// circular dependency. The effect is largely the same.
64+
function internalAssert(condition, message) {
65+
if (!condition) {
66+
throw new AssertionError({
67+
message,
68+
actual: false,
69+
expected: true,
70+
operator: '=='
71+
});
72+
}
73+
}
74+
6375
function message(key, args) {
64-
if (assert === null) assert = require('assert');
65-
assert.strictEqual(typeof key, 'string');
6676
const msg = messages.get(key);
67-
assert(msg, `An invalid error message key was used: ${key}.`);
77+
internalAssert(msg, `An invalid error message key was used: ${key}.`);
6878
let fmt;
6979
if (typeof msg === 'function') {
7080
fmt = msg;
@@ -184,6 +194,11 @@ E('ERR_HTTP2_UNSUPPORTED_PROTOCOL',
184194
(protocol) => `protocol "${protocol}" is unsupported.`);
185195
E('ERR_INDEX_OUT_OF_RANGE', 'Index out of range');
186196
E('ERR_INVALID_ARG_TYPE', invalidArgType);
197+
E('ERR_INVALID_ARRAY_LENGTH',
198+
(name, len, actual) => {
199+
internalAssert(typeof actual === 'number', 'actual must be a number');
200+
return `The array "${name}" (length ${actual}) must be of length ${len}.`;
201+
});
187202
E('ERR_INVALID_ASYNC_ID', (type, id) => `Invalid ${type} value: ${id}`);
188203
E('ERR_INVALID_CALLBACK', 'callback must be a function');
189204
E('ERR_INVALID_FD', (fd) => `"fd" must be a positive integer: ${fd}`);
@@ -239,7 +254,7 @@ E('ERR_VALID_PERFORMANCE_ENTRY_TYPE',
239254
// Add new errors from here...
240255

241256
function invalidArgType(name, expected, actual) {
242-
assert(name, 'name is required');
257+
internalAssert(name, 'name is required');
243258
var msg = `The "${name}" argument must be ${oneOf(expected, 'type')}`;
244259
if (arguments.length >= 3) {
245260
msg += `. Received type ${actual !== null ? typeof actual : 'null'}`;
@@ -248,7 +263,7 @@ function invalidArgType(name, expected, actual) {
248263
}
249264

250265
function missingArgs(...args) {
251-
assert(args.length > 0, 'At least one arg needs to be specified');
266+
internalAssert(args.length > 0, 'At least one arg needs to be specified');
252267
let msg = 'The ';
253268
const len = args.length;
254269
args = args.map((a) => `"${a}"`);
@@ -268,11 +283,12 @@ function missingArgs(...args) {
268283
}
269284

270285
function oneOf(expected, thing) {
271-
assert(expected, 'expected is required');
272-
assert(typeof thing === 'string', 'thing is required');
286+
internalAssert(expected, 'expected is required');
287+
internalAssert(typeof thing === 'string', 'thing is required');
273288
if (Array.isArray(expected)) {
274289
const len = expected.length;
275-
assert(len > 0, 'At least one expected value needs to be specified');
290+
internalAssert(len > 0,
291+
'At least one expected value needs to be specified');
276292
expected = expected.map((i) => String(i));
277293
if (len > 2) {
278294
return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` +

test/parallel/test-internal-errors.js

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@ const common = require('../common');
55
const errors = require('internal/errors');
66
const assert = require('assert');
77

8-
const errMessages = {
9-
objectString: /^'object' === 'string'$/,
10-
booleanString: /^'boolean' === 'string'$/,
11-
numberString: /^'number' === 'string'$/,
12-
invalidKey: /^An invalid error message key was used: TEST_FOO_KEY\.$/,
13-
};
8+
function invalidKey(key) {
9+
return new RegExp(`^An invalid error message key was used: ${key}\\.$`);
10+
}
1411

1512
errors.E('TEST_ERROR_1', 'Error for testing purposes: %s');
1613
errors.E('TEST_ERROR_2', (a, b) => `${a} ${b}`);
@@ -50,86 +47,86 @@ assert.throws(
5047
() => new errors.Error('TEST_FOO_KEY'),
5148
common.expectsError({
5249
code: 'ERR_ASSERTION',
53-
message: errMessages.invalidKey
50+
message: invalidKey('TEST_FOO_KEY')
5451
}));
5552
// Calling it twice yields same result (using the key does not create it)
5653
assert.throws(
5754
() => new errors.Error('TEST_FOO_KEY'),
5855
common.expectsError({
5956
code: 'ERR_ASSERTION',
60-
message: errMessages.invalidKey
57+
message: invalidKey('TEST_FOO_KEY')
6158
}));
6259
assert.throws(
6360
() => new errors.Error(1),
6461
common.expectsError({
6562
code: 'ERR_ASSERTION',
66-
message: errMessages.numberString
63+
message: invalidKey(1)
6764
}));
6865
assert.throws(
6966
() => new errors.Error({}),
7067
common.expectsError({
7168
code: 'ERR_ASSERTION',
72-
message: errMessages.objectString
69+
message: invalidKey('\\[object Object\\]')
7370
}));
7471
assert.throws(
7572
() => new errors.Error([]),
7673
common.expectsError({
7774
code: 'ERR_ASSERTION',
78-
message: errMessages.objectString
75+
message: invalidKey('')
7976
}));
8077
assert.throws(
8178
() => new errors.Error(true),
8279
common.expectsError({
8380
code: 'ERR_ASSERTION',
84-
message: errMessages.booleanString
81+
message: invalidKey('true')
8582
}));
8683
assert.throws(
8784
() => new errors.TypeError(1),
8885
common.expectsError({
8986
code: 'ERR_ASSERTION',
90-
message: errMessages.numberString
87+
message: invalidKey(1)
9188
}));
9289
assert.throws(
9390
() => new errors.TypeError({}),
9491
common.expectsError({
9592
code: 'ERR_ASSERTION',
96-
message: errMessages.objectString
93+
message: invalidKey('\\[object Object\\]')
9794
}));
9895
assert.throws(
9996
() => new errors.TypeError([]),
10097
common.expectsError({
10198
code: 'ERR_ASSERTION',
102-
message: errMessages.objectString
99+
message: invalidKey('')
103100
}));
104101
assert.throws(
105102
() => new errors.TypeError(true),
106103
common.expectsError({
107104
code: 'ERR_ASSERTION',
108-
message: errMessages.booleanString
105+
message: invalidKey('true')
109106
}));
110107
assert.throws(
111108
() => new errors.RangeError(1),
112109
common.expectsError({
113110
code: 'ERR_ASSERTION',
114-
message: errMessages.numberString
111+
message: invalidKey(1)
115112
}));
116113
assert.throws(
117114
() => new errors.RangeError({}),
118115
common.expectsError({
119116
code: 'ERR_ASSERTION',
120-
message: errMessages.objectString
117+
message: invalidKey('\\[object Object\\]')
121118
}));
122119
assert.throws(
123120
() => new errors.RangeError([]),
124121
common.expectsError({
125122
code: 'ERR_ASSERTION',
126-
message: errMessages.objectString
123+
message: invalidKey('')
127124
}));
128125
assert.throws(
129126
() => new errors.RangeError(true),
130127
common.expectsError({
131128
code: 'ERR_ASSERTION',
132-
message: errMessages.booleanString
129+
message: invalidKey('true')
133130
}));
134131

135132

0 commit comments

Comments
 (0)