-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
fix common.expectsError type checking
#13686
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
Conversation
|
I'm about 50% there. Looking for general feedback. |
test/parallel/test-dgram-bind.js
Outdated
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
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
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
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
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
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 TypeErrors.
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 Errors being accidently specialized.
|
Just to sum up, there are two levels of new assertions in 4 commits:
/cc @nodejs/testing |
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