Skip to content

Commit

Permalink
feat: pretty print diffs coming from cause (#5660)
Browse files Browse the repository at this point in the history
  • Loading branch information
dubzzz committed May 6, 2024
1 parent 6b29f3d commit 6faf8f8
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
13 changes: 10 additions & 3 deletions packages/utils/src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function normalizeErrorMessage(message: string) {
return message.replace(/__(vite_ssr_import|vi_import)_\d+__\./g, '')
}

export function processError(err: any, diffOptions?: DiffOptions) {
export function processError(err: any, diffOptions?: DiffOptions, seen = new WeakSet()) {
if (!err || typeof err !== 'object')
return { message: err }
// stack is not serialized in worker communication
Expand All @@ -121,9 +121,16 @@ export function processError(err: any, diffOptions?: DiffOptions) {
try {
if (typeof err.message === 'string')
err.message = normalizeErrorMessage(err.message)
}
catch {}

if (typeof err.cause === 'object' && typeof err.cause.message === 'string')
err.cause.message = normalizeErrorMessage(err.cause.message)
// some Error implementations may not allow rewriting cause
// in most cases, the assignment will lead to "err.cause = err.cause"
try {
if (!seen.has(err) && typeof err.cause === 'object') {
seen.add(err)
err.cause = processError(err.cause, diffOptions, seen)
}
}
catch {}

Expand Down
25 changes: 25 additions & 0 deletions test/core/test/error.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,28 @@ test('Can correctly process error where actual and expected contains non writabl

expect(() => processError(err)).not.toThrow(TypeError)
})

test('Can correctly process error where cause is a non writable property', () => {
const err = new Error('My error')

Object.defineProperty(err, 'cause', {
value: new Error('My cause'),
writable: false,
enumerable: true,
})

expect(() => processError(err)).not.toThrow(TypeError)
})

test('Can correctly process error where cause leads to an infinite recursion', () => {
const err = new Error('My error')

Object.defineProperty(err, 'cause', {
value: err,
writable: true,
enumerable: true,
configurable: true,
})

expect(() => processError(err)).not.toThrow()
})
13 changes: 13 additions & 0 deletions test/core/test/jest-expect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,19 @@ it('correctly prints diff', () => {
}
})

it('correctly prints diff for the cause', () => {
try {
expect({ a: 1 }).toEqual({ a: 2 })
expect.unreachable()
}
catch (err) {
setupColors(getDefaultColors())
const error = processError(new Error('wrapper', { cause: err }))
expect(error.cause.diff).toContain('- "a": 2')
expect(error.cause.diff).toContain('+ "a": 1')
}
})

it('correctly prints diff with asymmetric matchers', () => {
try {
expect({ a: 1, b: 'string' }).toEqual({
Expand Down

0 comments on commit 6faf8f8

Please sign in to comment.