Skip to content

Commit 21c3a40

Browse files
committed
assert: validate input stricter
This makes sure invalid `error` objects are not ignored when using `assert.throws` and `assert.rejects`. PR-URL: #20481 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>
1 parent c072057 commit 21c3a40

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

lib/assert.js

+10-6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const {
2828
const { codes: {
2929
ERR_AMBIGUOUS_ARGUMENT,
3030
ERR_INVALID_ARG_TYPE,
31+
ERR_INVALID_ARG_VALUE,
3132
ERR_INVALID_RETURN_VALUE
3233
} } = require('internal/errors');
3334
const { AssertionError, errorCache } = require('internal/assert');
@@ -414,12 +415,6 @@ function expectedException(actual, expected, msg) {
414415
);
415416
}
416417

417-
// TODO: Disallow primitives as error argument.
418-
// This is here to prevent a breaking change.
419-
if (typeof expected !== 'object') {
420-
return true;
421-
}
422-
423418
// Handle primitives properly.
424419
if (typeof actual !== 'object' || actual === null) {
425420
const err = new AssertionError({
@@ -438,6 +433,9 @@ function expectedException(actual, expected, msg) {
438433
// as well.
439434
if (expected instanceof Error) {
440435
keys.push('name', 'message');
436+
} else if (keys.length === 0) {
437+
throw new ERR_INVALID_ARG_VALUE('error',
438+
expected, 'may not be an empty object');
441439
}
442440
for (const key of keys) {
443441
if (typeof actual[key] === 'string' &&
@@ -527,6 +525,12 @@ function expectsError(stackStartFn, actual, error, message) {
527525
}
528526
message = error;
529527
error = undefined;
528+
} else if (error != null &&
529+
typeof error !== 'object' &&
530+
typeof error !== 'function') {
531+
throw new ERR_INVALID_ARG_TYPE('error',
532+
['Object', 'Error', 'Function', 'RegExp'],
533+
error);
530534
}
531535

532536
if (actual === NO_EXCEPTION_SENTINEL) {

test/parallel/test-assert.js

+23-4
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,21 @@ common.expectsError(
772772
}
773773
);
774774

775+
[
776+
1,
777+
false,
778+
Symbol()
779+
].forEach((input) => {
780+
assert.throws(
781+
() => assert.throws(() => {}, input),
782+
{
783+
code: 'ERR_INVALID_ARG_TYPE',
784+
message: 'The "error" argument must be one of type Object, Error, ' +
785+
`Function, or RegExp. Received type ${typeof input}`
786+
}
787+
);
788+
});
789+
775790
{
776791
const errFn = () => {
777792
const err = new TypeError('Wrong value');
@@ -871,6 +886,14 @@ common.expectsError(
871886
);
872887
}
873888

889+
assert.throws(
890+
() => assert.throws(() => { throw new Error(); }, {}),
891+
{
892+
message: "The argument 'error' may not be an empty object. Received {}",
893+
code: 'ERR_INVALID_ARG_VALUE'
894+
}
895+
);
896+
874897
assert.throws(
875898
() => a.throws(
876899
// eslint-disable-next-line no-throw-literal
@@ -981,7 +1004,3 @@ assert.throws(
9811004
}
9821005
);
9831006
}
984-
985-
// TODO: This case is only there to make sure there is no breaking change.
986-
// eslint-disable-next-line no-restricted-syntax, no-throw-literal
987-
assert.throws(() => { throw 4; }, 4);

0 commit comments

Comments
 (0)