diff --git a/doc/api/errors.md b/doc/api/errors.md index 3923780defa1e7..49834414decffe 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -586,6 +586,14 @@ found [here][online]. ## Node.js Error Codes + +### ERR_AMBIGUOUS_ARGUMENT + +This is triggered by the `assert` module in case e.g., +`assert.throws(fn, message)` is used in a way that the message is the thrown +error message. This is ambiguous because the message is not verifying the error +message and will only be thrown in case no error is thrown. + ### ERR_ARG_NOT_ITERABLE diff --git a/lib/assert.js b/lib/assert.js index 385ec332a6f999..0a505d553a405c 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -29,6 +29,7 @@ const { AssertionError, errorCache, codes: { + ERR_AMBIGUOUS_ARGUMENT, ERR_INVALID_ARG_TYPE } } = require('internal/errors'); @@ -470,6 +471,19 @@ function expectsError(stackStartFn, actual, error, message) { ['Object', 'Error', 'Function', 'RegExp'], error); } + if (typeof actual === 'object' && actual !== null) { + if (actual.message === error) { + throw new ERR_AMBIGUOUS_ARGUMENT( + 'error/message', + `The error message "${actual.message}" is identical to the message.` + ); + } + } else if (actual === error) { + throw new ERR_AMBIGUOUS_ARGUMENT( + 'error/message', + `The error "${actual}" is identical to the message.` + ); + } message = error; error = null; } diff --git a/lib/internal/errors.js b/lib/internal/errors.js index b190ae32bf6c8f..c8be91796ec249 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -640,6 +640,7 @@ module.exports = exports = { // // Note: Node.js specific errors must begin with the prefix ERR_ +E('ERR_AMBIGUOUS_ARGUMENT', 'The "%s" argument is ambiguous. %s', TypeError); E('ERR_ARG_NOT_ITERABLE', '%s must be iterable', TypeError); E('ERR_ASSERTION', '%s', Error); E('ERR_ASYNC_CALLBACK', '%s must be a function', TypeError); diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 4115167d4b48fd..c06155160495bc 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -836,3 +836,32 @@ common.expectsError( } ); } + +assert.throws( + () => a.throws( + // eslint-disable-next-line no-throw-literal + () => { throw 'foo'; }, + 'foo' + ), + { + code: 'ERR_AMBIGUOUS_ARGUMENT', + message: 'The "error/message" argument is ambiguous. ' + + 'The error "foo" is identical to the message.' + } +); + +assert.throws( + () => a.throws( + () => { throw new TypeError('foo'); }, + 'foo' + ), + { + code: 'ERR_AMBIGUOUS_ARGUMENT', + message: 'The "error/message" argument is ambiguous. ' + + 'The error message "foo" is identical to the message.' + } +); + +// Should not throw. +// eslint-disable-next-line no-restricted-syntax, no-throw-literal +assert.throws(() => { throw null; }, 'foo');