-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
The "cause" property of Error is ignored when matching #5697
Comments
This is documented behavior: https://vitest.dev/api/expect.html#toequal
|
Hi, @sheremet-va. Got it. Can you give me an example of using |
I don't believe Perhaps something like this? const error = vi.throws(fn)
expect(error).toEqual({ message: '', cause: '' }) |
@sheremet-va, also, any chance to revisit this?
I assume |
Technically you can use chai API for this: expect(() => {
throw new Error('test', { cause: new Error('cause') });
})
.throws()
.property('cause')
.eql(new Error('cause')) I am not sure what the best course of action is here, I also don't really like that it only checks the message. Will put it on the board to discuss with the team. If anyone has any ideas here, feel free to suggest here. Maybe adding |
I think there are a few possible directions to this:
That's a good call! I will remember this for myself but it won't work for what I'm preparing for my students right now. Not checking arbitrary properties is okay. But expect(fn).toThrow(new Error('message', { cause: 123 }))
Alternatively, if this worked it'd also be great: // Return me the error thrown by "fn"
// or throw if "fn" doesn't throw.
// Returning null is also fine, depends
// if we want to treat this as implicit assertion.
const error = vi.throws(fn)
expect(error.message).toBe('message')
expect(error.cause).toBe('cause') |
I see your point. It would be nice to check Not sure about |
Only if explicitly specified in the assertion 👍 const error = new Error('message', {
cause: new Error('another', {
cause: 123
})
})
expect(error).toEqual(new Error('message')) // OK!
expect(error).toEqual(new Error('message', { cause: new Error('another') })) // OK!
expect(error).toEqual(new Error('message', { cause: new Error('another', { cause: 123 }) })) // OK!
expect(error).toEqual(new Error('message', { cause: new Error('another', { cause: 'bad' }) })) // X
expect(error).toStrictEqual(new Error('message')) // X
expect(error).toStrictEqual(new Error('message', { cause: new Error('another') })) // X
expect(error).toStrictEqual(new Error('message', { cause: new Error('another', { cause: 'bad' }) })) // X
expect(error).toStrictEqual(new Error('message', { cause: new Error('another', { cause: 123 }) })) // OK! |
Something similar is brought up here Comparing only It turns out Node doesn't check import assert from "node:assert";
// ok
assert.deepStrictEqual(
new Error('x', { cause: 'foo' }),
new Error('x', { cause: 'bar' })
); This is not stopping Vitest from checking |
Update from my last comment, Node v22 actually started to check https://nodejs.org/docs/latest-v22.x/api/assert.html#assertdeepstrictequalactual-expected-message
I made a quick repro here https://github.com/hi-ogawa/reproductions/tree/main/node-error-equality and I can verify the new behavior, but they probably haven't considered adjusting error diff, so their current assertion error message is quite cryptic as it doesn't include It looks like this is added quite recently (and maybe prematurely?) nodejs/node#51805, so we might want to wait a bit longer how it turns out in node world. (Vitest also need to deal with how to format error diff properly since it currently only shows |
Hello, is there any chance to revisit this? As mentioned above in the thread, the |
Since EcmaScript 2022, `Error` objects support a `cause` property, allowing for tracking the root cause of an error. This commit set this property where appropriate. Since vitest's `toThrowError()` does not support checking the `cause` of an error [1], we use utility functions to catch and extract errors thrown by a function. This allows checking for individual properties of an error. [1]: vitest-dev/vitest#5697
This is how I do it import { it, expect } from "vitest";
it("should test cause", async () => {
const error = await myPromise().catch(e => JSON.parse(JSON.stringify(e)));
expect(error).toStrictEqual({ cause: "myCause" });
}) |
vitest/test/core/test/expect-poll.test.ts Lines 36 to 46 in 257d49d
|
— this approach is good, @hi-ogawa, but it does not provide a hint when such assertion fails: AssertionError: expected error to match asymmetric matcher
- Expected
+ Received
- ObjectContaining {
- "cause": "...",
- "message": "...",
- }
# no cause here:
+ [ErrorName: message] Here is my approach — a custom serializer for // vitest.setup.ts
expect.addSnapshotSerializer({
test: (subject: unknown) =>
subject instanceof Error && subject.cause !== undefined,
serialize: ({ name, message, cause }: Error) =>
`[${name}: ${message} (${cause})]`,
}); Then you can do expect(someFunction).toThrowErrorMatchingSnapshot() However, it affects the performance (23 —> 28s on single thread), because I wish there was an option in |
Describe the bug
Vitest ignores the
cause
property whenever performing any equality onError
instances.Reproduction
https://stackblitz.com/edit/vitest-dev-vitest-fq9xyu?file=test%2Fbasic.test.ts&initialPath=__vitest__/
System Info
Irrelevant. The issue is in the matcher.
Used Package Manager
npm
Validations
The text was updated successfully, but these errors were encountered: