-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix common.expectsError
type checking
#13686
fix common.expectsError
type checking
#13686
Conversation
I'm about 50% there. Looking for general feedback. |
test/parallel/test-dgram-bind.js
Outdated
@@ -31,7 +32,7 @@ socket.on('listening', common.mustCall(() => { | |||
socket.bind(); | |||
}, common.expectsError({ | |||
code: 'ERR_SOCKET_ALREADY_BOUND', | |||
type: Error, | |||
type: e.Error, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather this not check against the internal errors objects. These need to be recognizable as normal Error
, TypeError
and RangeError
instances.
test/parallel/test-fs-watchfile.js
Outdated
|
||
const expectedErr = common.expectsError({ | ||
type: Error, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please only use common.expectsError()
with errors that have been migrated to internal/errors
. The reason is so that the existing places in the tests where the error message is checked can be more easily found when doing the migration. If the tests already use common.expectsError()
, then it's far more likely that whoever is doing the migrating will miss those.
test/parallel/test-fs-watchfile.js
Outdated
Date.UTC(1970, 0, 1, 0, 0, 0), // atime | ||
Date.UTC(1970, 0, 1, 0, 0, 0), // mtime | ||
Date.UTC(1970, 0, 1, 0, 0, 0), // ctime | ||
Date.UTC(1970, 0, 1, 0, 0, 0) // birthtime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated whitespace changes
assert.strictEqual( | ||
errors.message('ERR_INVALID_URL_SCHEME', ['file']), | ||
'The URL must be of scheme file' | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why change the formatting on these?
Generally not a fan of updating the I'm definitely -1 on this PR as it currently stands. |
Ok. Thanks for the feedback. The other solution I had in mind is to use |
I don't know if I'd say inconsequential. We've given up some things by using custom errors. |
Like what? |
665dca2
to
f8405bc
Compare
common.expectsError
type checkingcommon.expectsError
type checking
Quick sanity: https://ci.nodejs.org/job/node-test-commit-linuxone/6638/
|
Correctly identifying an error seems to be very hard to do. Even our internal |
The following works well const errors = require('internal/errors');
const util = require('util');
const err = new err.Error('ERR_ASSERTION');
util.isError(err); // true
err instanceof Error; // true
err.constructor.prototype instanceof Error; // true |
Replace:
With:
And all three of those still report |
Well you two are commenting in a PR that fixes that 😉 |
As one should expect them to. This is not specific to assert.throws(() => { throw new TypeError() }, Error); That passes because The following is all correct behavior: const err = new err.TypeError('ERR_ASSERTION');
util.isError(err); // true
err instanceof Error; // true
err.constructor.prototype instanceof Error; // true |
test/parallel/test-fs-realpath.js
Outdated
@@ -225,7 +225,7 @@ function test_cyclic_link_protection(callback) { | |||
}); | |||
assert.throws(() => { | |||
fs.realpathSync(entry); | |||
}, common.expectsError({ code: 'ELOOP', type: Error })); | |||
}, /^Error: ELOOP: too many symbolic links encountered, stat/); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm -1 on changing this one. The check here is correct, tho the message check can be added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You asked that "regular" errors checks won't use common.expectsError
.
I'll check again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My apologies, I mean for errors that do not currently have a code
property. These do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack
test/common/index.js
Outdated
if (type !== undefined) | ||
assert(error instanceof type, | ||
`${error} is not the expected type ${type}`); | ||
if (expectedTypeName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not seeing why this increase in complexity is necessary. The instanceof
check works just fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because
var e = new TypeError();
e instanceof Error === true;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but that's ok. I don't see that it needs to be stricter than that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the purposes of our own test suite, I'd expect a TypeError
assertion to only work with TypeError
s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm with @cjihrig.
assert(err instanceof Error)
Does not protect for a change in the type of err
. The code could change it from Error
to TypeError
and the test would pass. Even changes from TypeError
to RangeError
would pass.
Those are semver-major
changes that we don't assert.
coreAPI.function(arg, (err, ret) => {
if (err instanceof TypeError) console.log('bad programer!');
if (err instanceof Error) console.log('oops');
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if I do common.expectsError({type: TypeError})
it will only be true
if the error is a TypeError
(or a subclass of TypeError
. If you'd like a stricter check, perhaps add a new argument like {strictType: TypeError}
so that tests that might happen to require absolutely strict checking can do so. Or, perhaps even allow type:
to take a function so stricter checking can be optionally performed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or a subclass of TypeError
That is the problem. In a recent PR, someone used common.expectsError()
with Error
, when they meant TypeError
. The test should have failed on this.
In our test suite we almost exclusively want the strictest error checks possible. Even if we were to add strictType
(which I don't think we should), how can we achieve that without exposing the fact that we're using the internal errors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the downcast case is covered, but the upcast is not (api that throw Error
changed to throw TypeError
, test still pass). I found one such case.
You know what will happen, we'll add strictType
then we'll deprecate type
and add a lint rule...
If you look at the change-set of the PR now, you'll see that enforcing strict type needs no test changes, and will protect from Error
s being accidently specialized.
Just to sum up, there are two levels of new assertions in 4 commits:
/cc @nodejs/testing |
@@ -215,10 +241,11 @@ assert.strictEqual(errors.message('ERR_MISSING_ARGS', ['name']), | |||
assert.strictEqual(errors.message('ERR_MISSING_ARGS', ['name', 'value']), | |||
'The "name" and "value" arguments must be specified'); | |||
assert.strictEqual(errors.message('ERR_MISSING_ARGS', ['a', 'b', 'c']), | |||
'The "a", "b", and "c" arguments must be specified'); | |||
'The "a", "b", and "c" arguments must be specified'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary whitespace change?
I'm generally still -1 on the stricter error type checking in |
PR-URL: nodejs#13686 Fixes: nodejs#13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
The function should strictly test for the error class and only accept the correct one. Any other error class should fail. PR-URL: nodejs#13686 Fixes: nodejs#13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
PR-URL: nodejs#13686 Fixes: nodejs#13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
The function should strictly test for the error class and only accept the correct one. Any other error class should fail. PR-URL: #13686 Fixes: #13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
PR-URL: #13686 Fixes: #13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
The function should strictly test for the error class and only accept the correct one. Any other error class should fail. PR-URL: #13686 Fixes: #13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
PR-URL: #13686 Fixes: #13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
This will need to be manually backported to v9.x as it is breaking a thing or two |
PR-URL: nodejs#13686 Fixes: nodejs#13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
The function should strictly test for the error class and only accept the correct one. Any other error class should fail. PR-URL: nodejs#13686 Fixes: nodejs#13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
PR-URL: nodejs#13686 Fixes: nodejs#13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
Backport-PR-URL: #19579 PR-URL: #13686 Fixes: #13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
The function should strictly test for the error class and only accept the correct one. Any other error class should fail. Backport-PR-URL: #19579 PR-URL: #13686 Fixes: #13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
Backport-PR-URL: #19579 PR-URL: #13686 Fixes: #13682 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
Backport requested for 8.x in #19244 |
Fixes: #13682
/cc @cjihrig @nodejs/testing
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
test