[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

fix(vitest): allow testing unandled rejection/exception (#6016)

authored by

Vladimir and committed by
GitHub
(Jul 1, 2024, 6:04 PM +0200) c8d56fe5 eb6ea5b3

+54 -3
+40
test/core/test/handled-unhandled.test.ts
··· 1 + import { nextTick } from 'node:process' 2 + import { expect, test, vi } from 'vitest' 3 + 4 + test('can test unhandled rejection', async () => { 5 + const fn = vi.fn() 6 + 7 + const promise = new Promise<void>((resolve) => { 8 + process.on('unhandledRejection', () => { 9 + fn() 10 + resolve() 11 + }) 12 + }) 13 + 14 + Promise.resolve().then(() => { 15 + throw new Error('unhandled rejection') 16 + }) 17 + 18 + await promise 19 + 20 + expect(fn).toHaveBeenCalledTimes(1) 21 + }) 22 + 23 + test('can test unhandled exception', async () => { 24 + const fn = vi.fn() 25 + 26 + const promise = new Promise<void>((resolve) => { 27 + process.on('uncaughtException', () => { 28 + fn() 29 + resolve() 30 + }) 31 + }) 32 + 33 + nextTick(() => { 34 + throw new Error('unhandled exception') 35 + }) 36 + 37 + await promise 38 + 39 + expect(fn).toHaveBeenCalledTimes(1) 40 + })
+14 -3
packages/vitest/src/runtime/execute.ts
··· 54 54 dispose.forEach(fn => fn()) 55 55 dispose.length = 0 56 56 57 - function catchError(err: unknown, type: string) { 57 + function catchError(err: unknown, type: string, event: 'uncaughtException' | 'unhandledRejection') { 58 58 const worker = state() 59 + 60 + // if error happens during a test 61 + if (worker.current) { 62 + const listeners = process.listeners(event as 'uncaughtException') 63 + // if there is another listener, assume that it's handled by user code 64 + // one is Vitest's own listener 65 + if (listeners.length > 1) { 66 + return 67 + } 68 + } 69 + 59 70 const error = processError(err) 60 71 if (!isPrimitive(error)) { 61 72 error.VITEST_TEST_NAME = worker.current?.name ··· 67 78 state().rpc.onUnhandledError(error, type) 68 79 } 69 80 70 - const uncaughtException = (e: Error) => catchError(e, 'Uncaught Exception') 71 - const unhandledRejection = (e: Error) => catchError(e, 'Unhandled Rejection') 81 + const uncaughtException = (e: Error) => catchError(e, 'Uncaught Exception', 'uncaughtException') 82 + const unhandledRejection = (e: Error) => catchError(e, 'Unhandled Rejection', 'unhandledRejection') 72 83 73 84 process.on('uncaughtException', uncaughtException) 74 85 process.on('unhandledRejection', unhandledRejection)