-
-
Notifications
You must be signed in to change notification settings - Fork 108
Two different Errors are considered equal #47
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
Comments
@agirorn #58 I want to know your opinion 😄 Thank you 👍 |
FYI @RusinovAnton |
I think that errors are only equal in the following conditions:
|
More that they need to have the same properties, enumerable or not - which includes |
@ljharb you might be on to something here. I just did some minor experiments and have found out that node 12 (Object.keys) and object-keys do not return all the keys for all properties on an instance of the Error class. > Object.keys(new Error('a'))
[]
> const keys = require('object-keys');
> keys(new Error('a'))
│[]
> class T { constructor() { this.key = 'VALUE'; }}
> Object.keys(new T())
[ 'key' ] So maybe it is just a javascript issue and then the question is should this model try to fix this strange behavior of javascript or should the user of this module just feed in the correct object that can be checked for equality? const equal = require('deep-equal');
const a = new Error('a')
const b = new Error('a')
const A = {
message: a.message,
className: a.constructor.name
};
const B = {
message: b.message,
className: b.constructor.name
};
console.dir([
A,
B,
equal(A, B, { strict: true })
])
// [
// { message: 'a', className: 'Error' },
// { message: 'b', className: 'Error' },
// false
// ] As far as I'm concerned this issue can be closed. |
That's because The real question is, what does |
node 12
|
I also see these: assert.deepStrictEqual(new Error('a'), new Error('a')); // passes
assert.deepStrictEqual(new Error('a'), new Error('b')); // throws
assert.deepEqual(new Error(), new TypeError()); // throws
assert.deepStrictEqual(new Error(), new TypeError()); // throws
assert.deepEqual(new Error(), Object.setPrototypeOf(new TypeError(), Error.prototype)); // passes
assert.deepStrictEqual(new Error(), Object.setPrototypeOf(new TypeError(), Error.prototype)); // passes
assert.deepEqual(new Error(), Object.assign(new Error(), { a: 1 })); // throws
assert.deepStrictEqual(new Error(), Object.assign(new Error(), { a: 1 })); // throws Which suggests that it's comparing the I then, however, compared this: var e1 = new Error('a');
var e2 = { __proto__: Error.prototype };
Object.defineProperties(e2, Object.getOwnPropertyDescriptors(e1));
assert.deepEqual(Reflect.ownKeys(e1), Reflect.ownKeys(e2)); // passes
assert.deepStrictEqual(Reflect.ownKeys(e1), Reflect.ownKeys(e2)); // passes
assert.deepEqual(Object.getPrototypeOf(e1), Object.getPrototypeOf(e2)); // passes
assert.deepStrictEqual(Object.getPrototypeOf(e1), Object.getPrototypeOf(e2)); // passes
assert.equal(e1 instanceof Error, e2 instanceof Error); // passes
assert.deepEqual(e1, e2); // throws
assert.deepStrictEqual(e1, e2); // throws and separately, non-enumerable properties are not compared on non-errors: var o1 = { message: 'a' };
var o2 = { message: 'a' };
Object.defineProperty(o2, 'message', { enumerable: false });
assert.deepEqual(o1, o2); // throws
assert.deepStrictEqual(o1, o2); // throws
Object.defineProperty(o1, 'message', { enumerable: false });
assert.deepEqual(o1, o2); // passes
assert.deepStrictEqual(o1, o2); // passes
o2.message = 'b';
assert.deepEqual(o1, o2); // passes
assert.deepStrictEqual(o1, o2); // passes which suggests that there is, unfortunately, Error-specific checking - presumably some kind of brand check that we'll be unable to do at runtime, and that non-enumerable properties are only checked on Errors and not on normal objects. |
The issue is that there's no runtime way of brand-checking Error objects, and |
https://runkit.com/57e01e376dc2ad1400d39ab3/584826c627aa8e0013a1adcd
The text was updated successfully, but these errors were encountered: