-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Add error serializer #3655
Comments
Can't you just use |
I was hoping that, but no, that didn't work 😥 I think I also found the place where the error is converted, and there it's just |
Looks like a bug. I would assume it to be affected |
Hi, I'm curious about this issue and I'd like to confirm what's expected to work or not work. I'm experimenting with OP's example locally and I put reproduction at the bottom.
Could someone confirm whether custom serializer should be applied for 2nd case as well? Given that first case works, I also included potential workaround for users in the snippet below. reveal full snippettest('custom serializer against thrown instance', async () => {
class ErrorWithDetails extends Error {
readonly details: unknown
constructor(message: string, options: ErrorOptions & { details: unknown }) {
super(message, options)
this.details = options.details
}
}
// without custom serializer
const error = new ErrorWithDetails('Example', { details: 'interesting detail' })
expect(() => {
throw error
}).toThrowErrorMatchingInlineSnapshot(`"Example"`)
expect(error).toMatchInlineSnapshot(`[Error: Example]`)
// with custom serializer
expect.addSnapshotSerializer({
serialize(val, config, indentation, depth, refs, printer) {
const error = val as ErrorWithDetails
return `${error.message}: ${printer(error.details, config, indentation, depth, refs)}`
},
test(val) {
return val && val instanceof ErrorWithDetails
},
})
expect(() => {
throw error
}).toThrowErrorMatchingInlineSnapshot(`"Example"`) // serializer not applied
expect(error).toMatchInlineSnapshot(`Example: "interesting detail"`) // serializer applied
//
// workaround 1 (for async error)
// by unwrapping with `rejects, it can assert error instance via `toMatchInlineSnapshot`
//
await expect(async () => {
throw error
}).rejects.toMatchInlineSnapshot(`Example: "interesting detail"`)
//
// workaround 2
// create a utility to catch error and use it to assert snapshot via `toMatchInlineSnapshot`
//
function wrapError<T>(f: () => T): { success: true; data: T } | { success: false; error: unknown } {
try {
return { success: true, data: f() }
}
catch (error) {
return { success: false, error }
}
}
expect(wrapError(() => {
throw error
})).toMatchInlineSnapshot(`
{
"error": Example: "interesting detail",
"success": false,
}
`)
}) While looking around the code, it looks like vitest/packages/vitest/src/integrations/snapshot/chai.ts Lines 143 to 144 in ba1df84
But changing here might be a huge breaking change function getErrorString(expected: () => void | Error, promise: string | undefined) {
...
catch (e) {
- return getErrorMessage(e)
+ return e
}
...
} since this will lead to a different default throw snapshot: // before
expect(() => {
throw new Error('omega')
}).toThrowErrorMatchingInlineSnapshot(`"ometa"`)
// after
expect(() => {
throw new Error('omega')
}).toThrowErrorMatchingInlineSnapshot(`[Error: omega]`) EDIT: I created a draft PR as it might help the discussion better with concrete code. #4396 |
@hi-ogawa I came to exactly the same conclusion. Before creating a PR, I wanted to confirm that this is really an issue. Thanks for creating the PR, looks promising! |
Clear and concise description of the problem
Custom errors with additional attributes are hard to test using
toThrowErrorMatchingInlineSnapshot
Example:
Suggested solution
Add an
addErrorSerializer
which works likeaddSnapshotSerializer
, but for errors.Example:
which could then result in:
Alternative
We can work around that issue, but it is cumbersome:
Additional context
No response
Validations
The text was updated successfully, but these errors were encountered: