-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Compare errors by identity in _.isEqual #2882
Comments
Errors are special because all their properties are prototype getters. Why do you want to compare them for equality? |
Thank you for the very prompt reply @jgonggrijp I came across this in a client's library that uses backbonejs. Registered listeners should receive notification when attributes change. One of the attributes was an error. Changes to that attribute did not generate any notifications. Dug in and arrived here. |
Welcome. Makes sense. A few more questions:
Sorry to be so inquisitive. Errors are special beasts, so I'm still undecided on what would be the most reasonable course of action. |
No worries - I share your trepidation to jump onto a solution - I expect the authors, contributors and maintainers of such a long standing library have already spent considerable time on this.
The model manages facets of a speech recognition process that can contain an errors.
My first consideration would be to explicitly include both standard, and non-standard properties listed on MDN in the keys used for deep compare. I believe it would return the least surprising result and reasonably handle enumerable properties added when extending Error. something along the lines of: // isEqual#122
if (className === '[object Error]') {
_keys =_keys.concat(['a bunch of properties'])
length = _keys.length
}
For this client, I generated a string to represent the error and used that value instead - and left a nice note to let everyone else know that they cannot use error objects as I expect anyone, myself included, would look at that code in six months and ask 'Why are we creating a custom string representation here?' |
I'm glad we're on the same page with regard to not jumping to solutions. I don't think the fix you're proposing for Line 124 in d9741b3
Semantically, the most correct thing to do might actually be to check for object identity, i.e., That would mean that |
You are absolutely correct. !has(a, key) properties would need to be excluded from whatever was added to _keys. There are other options as well, such as using a separate while block entirely or extracting out the Array, Object and Error comparison processes. Regardless, your idea is great. It would be a clean, minimal change that precisely solves this specific problem. Is there any concern that any implementation would be a a breaking change? Cloning methods based on getOwnPropertyNames may be expecting underscore to treat those 'clones' as equal when comparing error instances. |
Yes, breaking changes are a concern. If a breaking change is purely a bugfix (bugfixes are in a sense always "breaking" changes), then we can get away with putting it in a minor update, but otherwise, it needs to be postponed until Underscore 2.0. An example of such a change is #2815. Errors are a bit of an edge case, which always makes it a bit fuzzy whether you're actually making the code more correct or just making a different arbitrary choice. While I do believe that errors are unique, there might be somebody out there using
Fortunately, this won't change; the following code already returns var x = new Error();
_.isEqual(x, _.clone(x)); Also, the following would continue to return _.isEqual(_.clone(x), _.clone(x)); |
TLDR @jashkenas:
|
I have the same issue after updating from 1.10.2 to 1.11.0:
|
@meyraa I don't think this is the same issue. Moreover, it appears I fixed the comparison of |
@jgonggrijp Thank you, the bleeding edge version works fine. |
@jashkenas informed me he won't have time to look at this issue for a while. I'm not in a rush, so I'm just leaving this open so I can give it more thought. @captbaritone @michaelficarra @paulfalgout @joshuacc (or anyone else) if you feel like giving an opinion, I'm interested. |
I think you’ve all arrived at very reasonable conclusions here. Special casing To the larger point about version numbers — cases like this are a clean example of why I do not believe in Semantic Versioning. As long as one man’s bugfix is another man’s breaking change, the scheme is unworkable. But that leaves us with the pragmatic decision: to avoid the potential for anger, we should wait to release this change until 2.0. |
Thanks for stepping in anyway, @jashkenas! While I'm a bit more optimistic about semver, I can follow your reasoning. I'll slap a "change" label onto this and I'll also create a 2.0 milestone while I'm at it. |
Edit bij @jgonggrijp: tldr link.
Is this intentional?
This holds true for extensions as well...
Other built in types (e.g. Date, RegExp, Symbol) have various methods to coerce for comparison.
Error comparison ends up in deep equality comparison, which relies on Object.keys and ends up comparing empty arrays.
Happy to send in a PR if this is unintentional, also happy to work around it if it is.
The text was updated successfully, but these errors were encountered: