Skip to content
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

feat: uncaught errors to indicate env teardown #2982

Merged
merged 1 commit into from
Mar 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/vitest/src/node/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export async function printError(error: unknown, ctx: Vitest, options: PrintErro

const testPath = (e as any).VITEST_TEST_PATH
const testName = (e as any).VITEST_TEST_NAME
const afterEnvTeardown = (e as any).VITEST_AFTER_ENV_TEARDOWN
// testName has testPath inside
if (testPath)
ctx.logger.error(c.red(`This error originated in "${c.bold(testPath)}" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.`))
Expand All @@ -76,6 +77,11 @@ export async function printError(error: unknown, ctx: Vitest, options: PrintErro
+ '\n- The error was thrown, while Vitest was running this test.'
+ '\n- This was the last recorded test before the error was thrown, if error originated after test finished its execution.'))
}
if (afterEnvTeardown) {
ctx.logger.error(c.red('This error was caught after test environment was torn down. Make sure to cancel any running tasks before test finishes:'
+ '\n- cancel timeouts using clearTimeout and clearInterval'
+ '\n- wait for promises to resolve using the await keyword'))
}

if (typeof e.cause === 'object' && e.cause && 'name' in e.cause) {
(e.cause as any).name = `Caused by: ${(e.cause as any).name}`
Expand Down Expand Up @@ -113,6 +119,7 @@ const skipErrorProperties = new Set([
'expected',
'VITEST_TEST_NAME',
'VITEST_TEST_PATH',
'VITEST_AFTER_ENV_TEARDOWN',
...Object.getOwnPropertyNames(Error.prototype),
...Object.getOwnPropertyNames(Object.prototype),
])
Expand Down
2 changes: 2 additions & 0 deletions packages/vitest/src/runtime/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,6 @@ export async function run(files: string[], config: ResolvedConfig, environment:

await stopCoverageInsideWorker(config.coverage, executor)
})

workerState.environmentTeardownRun = true
}
2 changes: 2 additions & 0 deletions packages/vitest/src/runtime/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export async function startViteNode(ctx: ContextRPC) {
error.VITEST_TEST_NAME = worker.current?.name
error.VITEST_TEST_PATH = relative(config.root, worker.filepath)
}
error.VITEST_AFTER_ENV_TEARDOWN = worker.environmentTeardownRun

rpc().onUnhandledError(error, type)
}

Expand Down
1 change: 1 addition & 0 deletions packages/vitest/src/types/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface WorkerGlobalState {
rpc: BirpcReturn<RuntimeRPC>
current?: Test
filepath?: string
environmentTeardownRun?: boolean
moduleCache: ModuleCacheMap
mockMap: MockMap
}
16 changes: 0 additions & 16 deletions test/core/test/dom.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,19 +171,3 @@ it('doesn\'t throw, if listening for error', () => {
dispatchEvent(new Event('custom'))
expect(spy).toHaveBeenCalled()
})

it('timers are not run after environment teardown', async () => {
AriPerkkio marked this conversation as resolved.
Show resolved Hide resolved
setInterval(() => {
try {
window.document.createElement('div')
}
catch (err) {
if (/window is not defined/.test((err as any).message))
throw new Error('setInterval was called after environment teardown')

throw err
}
}, 1)

expect(window.document).toBeDefined()
})