You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm implementing tests for my js project and I need to compare an error returned from a rejected promise with an expected one.
It turns out that, no mater what is the content of the error object, assert.deepEqual always returns true as long as the two instances being compared are Errors.
The same behaviour does not occur when comparing strings, for example (node version 4.1.1):
node --version
v4.1.1
> let assert = require("assert");
undefined
> assert.deepEqual(new Error("a"), new Error("b"));
undefined
> assert.deepEqual(new String("a"), new String("b"));
AssertionError: [String: 'a'] deepEqual [String: 'b']
at repl:1:8
at REPLServer.defaultEval (repl.js:164:27)
at bound (domain.js:250:14)
at REPLServer.runBound [as eval] (domain.js:263:12)
at REPLServer.<anonymous> (repl.js:393:12)
at emitOne (events.js:82:20)
at REPLServer.emit (events.js:169:7)
at REPLServer.Interface._onLine (readline.js:210:10)
at REPLServer.Interface._line (readline.js:549:8)
at REPLServer.Interface._ttyWrite (readline.js:826:14)
Is this behaviour intended by design? Am I missing something important or should a consider another strategy to deeply compare two Error objects (instances + messages)?
I'm afraid a fix for this is unlikely to land in Node.js. The API is now locked and users are encouraged to employ userland assertion libraries instead.
If you don't want to use a userland assertion library for whatever reason, a workaround for your case might look like this:
Or, more thoroughly (like, if you want the stack traces to match exactly, which you typically probably don't):
var ka = Object.getOwnPropertyNames(error1).concat(Object.getOwnPropertySymbols(error1));
var kb = Object.getOwnPropertyNames(error1).concat(Object.getOwnPropertySymbols(error2));
ka.sort();
kb.sort();
assert.deepStrictEqual(ka, kb);
for (var i = ka.length - 1; i >= 0; i--) {
console.log(ka[i]);
assert.deepEqual(error1[ka[i]], error2[ka[i]]); // use assert.deepStrictEqual() if that's what you want
}
Activity
Trott commentedon Sep 30, 2015
This looks like it's caused by code in
lib/assert.jsthat usesObject.keys()to get all the keys in theErrorobjects and then compares them. TheErrorobjects have non-enumerable keys soObject.keys(new Error('a'));returns an empty array. So the errors are determined to be equal.Trott commentedon Sep 30, 2015
Possible fix: #3124
Trott commentedon Oct 19, 2015
I'm afraid a fix for this is unlikely to land in Node.js. The API is now locked and users are encouraged to employ userland assertion libraries instead.
If you don't want to use a userland assertion library for whatever reason, a workaround for your case might look like this:
Or, more thoroughly (like, if you want the stack traces to match exactly, which you typically probably don't):
doc: add information about Assert behavior and maintenance
doc: add information about Assert behavior and maintenance
doc: add information about Assert behavior and maintenance