Skip to content
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

assert: handle errors properly with deep*Equal #15001

Closed
wants to merge 1 commit into from

Conversation

BridgeAR
Copy link
Member

Since the assert module is not locked anymore it became much better over time (at least the strict part). But it still does not compare Errors and that is really a pain. I feels natural that this would throw.

This introduces such a check. Fixes #3122

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

assert

@nodejs-github-bot nodejs-github-bot added the assert Issues and PRs related to the assert subsystem. label Aug 24, 2017
Copy link
Member

@TimothyGu TimothyGu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about stack?

@BridgeAR
Copy link
Member Author

@TimothyGu the stack is explicitly not checked as it would always differ depending on where you created the Error. The object itself can be completely identical otherwise and this is also how it is done in most libraries (I am not aware that any checks for the stack).

@BridgeAR BridgeAR added the semver-major PRs that contain breaking changes and should be released in the next major version. label Aug 24, 2017
Copy link
Member

@Trott Trott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM although I have a comment/question on the doc change.

not enumerable:

```js
// WARNING: This does not throw an AssertionError!
assert.deepEqual(Error('a'), Error('b'));
assert.deepEqual(/a/, {});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can either come up with a better example or if it's OK to just remove the example entirely. The current one makes it so clear that intuition would be wrong, but this one not so much. This seems more akin to assert.deepEqual('', 0) than the current example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert.deepEqual(new Date(), new Uint8Array())?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh , yeah, I think it's definitely less obvious with a Date object that there aren't enumerable properties!

I think something like this might be even better:

assert.deepEqual(new Date(), /a/);

My thinking is that those are two objects where the absence of enumerable properties is easy to forget. So that result is genuinely surprising at a glance.

In contrast, the idea that an empty object or an empty array don't have enumerable properties is more obvious.

I might be overthinking this a bit. :-D

@BridgeAR
Copy link
Member Author

I updated the example and also made the check in general more strict as it now also checks for weird inheritance. That was a oversight before and now it will handle those properly as well.

While thinking about it I would actually do not consider this a semver-major but a bug fix because most people would anticipate that errors would be compared. Other opinions about this?

@BridgeAR BridgeAR removed the semver-major PRs that contain breaking changes and should be released in the next major version. label Aug 25, 2017
@BridgeAR
Copy link
Member Author

I actually removed the weird inheritance again because I think we should not support that.

@BridgeAR
Copy link
Member Author

@jasnell
Copy link
Member

jasnell commented Aug 25, 2017

Is this semver-major?

@BridgeAR
Copy link
Member Author

@jasnell I count this as a bugfix and it would only now show errors in cases where people actually wanted to get an error as you would probably otherwise not use deepEqual on errors in the first place otherwise.

@BridgeAR
Copy link
Member Author

Ping @jasnell

@jasnell
Copy link
Member

jasnell commented Aug 29, 2017

I can go with that :)

@BridgeAR
Copy link
Member Author

Rebased due to conflicts

@BridgeAR
Copy link
Member Author

It would be nice to get some more reviews @nodejs/collaborators

@@ -230,6 +237,10 @@ function looseDeepEqual(actual, expected) {
if (isRegExp(actual) && isRegExp(expected)) {
return areSimilarRegExps(actual, expected);
}
if (actual instanceof Error && expected instanceof Error) {
if (actual.message !== expected.message || actual.name !== expected.name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you compare code as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code will be compared if it is set by the user as a non enumerable property. This is only intended for the non enumerable properties message and name from the default Error classes and not for userland sub-classing.

Copy link
Contributor

@refack refack Aug 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh Ok. The keys of expected are the assertion demand.
(I was thinking of the case of trying to assert a NodeError where .code comes from the prototype)
So will this be an effective check?

assert.deepStrictEqual(someNodeError, Object.assign(new Error(msg), {code: ERR_CODE}));

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would fail because the left prototype is not the same as the right one.

@BridgeAR
Copy link
Member Author

BridgeAR commented Sep 1, 2017

Landed in 204d94f

@BridgeAR BridgeAR closed this Sep 1, 2017
BridgeAR added a commit that referenced this pull request Sep 1, 2017
PR-URL: #15001
Reviewed-By: Rich Trott <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
addaleax pushed a commit to addaleax/ayo that referenced this pull request Sep 5, 2017
PR-URL: nodejs/node#15001
Reviewed-By: Rich Trott <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
MylesBorins pushed a commit that referenced this pull request Sep 10, 2017
PR-URL: #15001
Reviewed-By: Rich Trott <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
@MylesBorins MylesBorins mentioned this pull request Sep 10, 2017
MylesBorins pushed a commit that referenced this pull request Sep 12, 2017
PR-URL: #15001
Reviewed-By: Rich Trott <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
@MylesBorins
Copy link
Contributor

Should this be backported to v6.x-staging? If yes please follow the guide and raise a backport PR, if no let me know or add the dont-land-on label.

@BridgeAR
Copy link
Member Author

#13862 should be backported first. I opened a PR for that and I will look into backporting this after it landed.

@BridgeAR
Copy link
Member Author

Hm, there are quite a few commits that should be backported before this one. @MylesBorins if you want that I could make a single backport with all assert commits that I guess make sense to backport.

@BridgeAR BridgeAR deleted the assert-errors branch April 1, 2019 23:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
assert Issues and PRs related to the assert subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants