[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(browser): print related test file and potential test in unhandled errors (#7564)

authored by

Vladimir and committed by
GitHub
(Feb 27, 2025, 1:54 PM +0900) fee90d85 d5cb8212

+22 -7
+2
test/browser/specs/unhandled.test.ts
··· 7 7 }) 8 8 9 9 expect(stderr).toContain('throw-unhandled-error.test.ts:9:10') 10 + expect(stderr).toContain('This error originated in "throw-unhandled-error.test.ts" test file.') 11 + expect(stderr).toContain('The latest test that might\'ve caused the error is "unhandled exception".') 10 12 11 13 if (instances.some(({ browser }) => browser === 'webkit')) { 12 14 expect(stderr).toContain('throw-unhandled-error.test.ts:9:20')
+2 -2
packages/vitest/src/node/error.ts
··· 141 141 }) 142 142 143 143 if (type) { 144 - printErrorType(type, project.ctx) 144 + printErrorType(type, project.vitest) 145 145 } 146 146 printErrorMessage(e, logger) 147 147 if (options.screenshotPaths?.length) { ··· 205 205 logger.error( 206 206 c.red( 207 207 `This error originated in "${c.bold( 208 - testPath, 208 + relative(project.config.root, testPath), 209 209 )}" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.`, 210 210 ), 211 211 )
+4 -4
packages/vitest/src/runtime/execute.ts
··· 6 6 import { pathToFileURL } from 'node:url' 7 7 import vm from 'node:vm' 8 8 import { processError } from '@vitest/utils/error' 9 - import { normalize, relative } from 'pathe' 9 + import { normalize } from 'pathe' 10 10 import { DEFAULT_REQUEST_STUBS, ViteNodeRunner } from 'vite-node/client' 11 11 import { 12 12 isInternalRequest, ··· 59 59 const worker = state() 60 60 61 61 // if error happens during a test 62 - if (worker.current) { 62 + if (worker.current?.type === 'test') { 63 63 const listeners = process.listeners(event as 'uncaughtException') 64 64 // if there is another listener, assume that it's handled by user code 65 65 // one is Vitest's own listener ··· 70 70 71 71 const error = processError(err) 72 72 if (!isPrimitive(error)) { 73 - error.VITEST_TEST_NAME = worker.current?.name 73 + error.VITEST_TEST_NAME = worker.current?.type === 'test' ? worker.current.name : undefined 74 74 if (worker.filepath) { 75 - error.VITEST_TEST_PATH = relative(state().config.root, worker.filepath) 75 + error.VITEST_TEST_PATH = worker.filepath 76 76 } 77 77 error.VITEST_AFTER_ENV_TEARDOWN = worker.environmentTeardownRun 78 78 }
+4 -1
test/browser/fixtures/unhandled/throw-unhandled-error.test.ts
··· 4 4 _fake: never 5 5 } 6 6 7 - test('unhandled exception', () => { 7 + test('unhandled exception', async () => { 8 8 ;(async () => { 9 9 throw new Error('custom_unhandled_error') 10 10 })() 11 + // trigger the error during the test so the report includes the helpful message 12 + // in reality, most tests will have something going on here already 13 + await new Promise<void>((resolve) => setTimeout(() => resolve(), 50)) 11 14 })
+10
packages/browser/src/client/public/error-catcher.js
··· 1 1 import { channel, client } from '@vitest/browser/client' 2 2 3 3 function serializeError(unhandledError) { 4 + const state = globalThis.__vitest_worker__ 5 + const VITEST_TEST_NAME = state && state.current && state.current.type === 'test' 6 + ? state.current.name 7 + : undefined 8 + const VITEST_TEST_PATH = state && state.filepath ? state.filepath : undefined 9 + 4 10 if (typeof unhandledError !== 'object' || !unhandledError) { 5 11 return { 6 12 message: String(unhandledError), 13 + VITEST_TEST_NAME, 14 + VITEST_TEST_PATH, 7 15 } 8 16 } 9 17 ··· 11 19 name: unhandledError.name, 12 20 message: unhandledError.message, 13 21 stack: String(unhandledError.stack), 22 + VITEST_TEST_NAME, 23 + VITEST_TEST_PATH, 14 24 } 15 25 } 16 26