Skip to content

Commit

Permalink
assert: wrap validation function errors
Browse files Browse the repository at this point in the history
This makes sure that validation function used by `assert.throws` and
`assert.rejects` always throw validatin errors instead of rethrowing
the received error.

That should improve the debugging experience for developers since
they have a better context where the error is coming from and they
also get to know what triggered it.

PR-URL: #28263
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
BridgeAR committed Oct 1, 2019
1 parent 0b3242c commit d47b678
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 1 deletion.
3 changes: 3 additions & 0 deletions doc/api/assert.md
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,9 @@ assert.throws(

Custom error validation:

The function must return `true` to indicate all internal validations passed.
It will otherwise fail with an AssertionError.

```js
assert.throws(
() => {
Expand Down
16 changes: 15 additions & 1 deletion lib/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,21 @@ function expectedException(actual, expected, message, fn) {
// Check validation functions return value.
const res = expected.call({}, actual);
if (res !== true) {
throw actual;
if (!message) {
generatedMessage = true;
const name = expected.name ? `"${expected.name}" ` : '';
message = `The ${name}validation function is expected to return "true".` +
` Received ${inspect(res)}`;
}
const err = new AssertionError({
actual,
expected,
message,
operator: fn.name,
stackStartFn: fn
});
err.generatedMessage = generatedMessage;
throw err;
}
}

Expand Down
15 changes: 15 additions & 0 deletions test/parallel/test-assert-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,21 @@ const invalidThenableFunc = () => {
code: 'ERR_INVALID_RETURN_VALUE'
})
);

const err = new Error('foobar');
const validate = () => { return 'baz'; };
promises.push(assert.rejects(
() => assert.rejects(Promise.reject(err), validate),
{
message: 'The "validate" validation function is expected to ' +
"return \"true\". Received 'baz'",
code: 'ERR_ASSERTION',
actual: err,
expected: validate,
name: 'AssertionError',
operator: 'rejects',
}
));
}

{
Expand Down
17 changes: 17 additions & 0 deletions test/parallel/test-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -1326,3 +1326,20 @@ assert.throws(
'Received "[Array]"'
}
);

{
const err = new TypeError('foo');
const validate = (() => () => ({ a: true, b: [ 1, 2, 3 ] }))();
assert.throws(
() => assert.throws(() => { throw err; }, validate),
{
message: 'The validation function is expected to ' +
`return "true". Received ${inspect(validate())}`,
code: 'ERR_ASSERTION',
actual: err,
expected: validate,
name: 'AssertionError',
operator: 'throws',
}
);
}

0 comments on commit d47b678

Please sign in to comment.