Skip to content

fix(pool): improve error message when worker exits unexpectedly#10587

Merged
AriPerkkio merged 10 commits into
vitest-dev:mainfrom
filmaj:raise-code-signal
Jun 22, 2026
Merged

fix(pool): improve error message when worker exits unexpectedly#10587
AriPerkkio merged 10 commits into
vitest-dev:mainfrom
filmaj:raise-code-signal

Conversation

@filmaj

@filmaj filmaj commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Description

In a large project leveraging vitest, with heavy integration test setup routines involved, we noticed sometimes the test worker threads would 'unexpectedly exit' but without much information. Poking around the code, it seems like the child-process-based pool workers expose code and signal to exit events. Worker threads expose exit codes, though no signal.

However, vitest doesn't expose that information in the case that forks or worker thread-based pool workers exit unexpectedly. This information was helpful for us to diagnose at least one test 'flakiness' issue we encountered (SIGSEGV when native extensions were dipping into global shared memory spaces).

This PR is a conversation starting point as I'm a first-timer contributor to vitest! I am missing a few things in the checklist below and am open to any feedback on how to make this PR easier to review / accept.

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. If the feature is substantial or introduces breaking changes without a discussion, PR might be closed.
  • Ideally, include a test that fails without this PR but passes with it.
  • Please, don't make changes to pnpm-lock.yaml unless you introduce a new test example.
  • Please check Allow edits by maintainers to make review process faster. Note that this option is not available for repositories that are owned by Github organizations.

Tests

  • Run the tests with pnpm test:ci.
    • I did, though I got a 'worker unexpectedly exited' error running this command on main - which is ironic given what this PR does!

Documentation

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs command.

Changesets

  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.

Comment thread test/coverage-test/fixtures/src/query-param-transformed.ts Outdated
Comment thread packages/vitest/src/node/pools/types.ts
Comment thread packages/vitest/src/node/pools/poolRunner.ts Outdated

@AriPerkkio AriPerkkio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test case for this could be in

import { runVitest, StableTestFileOrderSorter } from '#test-utils'
import { resolve } from 'pathe'
import { expect, test } from 'vitest'
import { readCoverageMap } from '../../coverage-test/utils'
test('worker death on a shared runner does not skip coverage finalization', async () => {
const root = './fixtures/pool-worker-exit'
const { buildTree } = await runVitest({
root,
pool: 'forks',
// Disable isolation to make sure crashed worker doesn't hang whole test run
isolate: false,
maxWorkers: 2,
sequence: { sequencer: StableTestFileOrderSorter },
include: [
'1-first.test.ts',
'2-crash.test.ts',
'3-crash.test.ts',
'4-third.test.ts',
],
reporters: 'default',
coverage: {
enabled: true,
provider: 'v8',
reporter: ['json'],
reportOnFailure: true,
},
})
expect(buildTree(t => ({ state: t.result().state }))).toMatchInlineSnapshot(`
{
"1-first.test.ts": {
"first test exercises src so it should appear in coverage": {
"state": "passed",
},
},
"2-crash.test.ts": {
"the worker dies before sending testfileFinished": {
"state": "pending",
},
},
"3-crash.test.ts": {
"the worker dies before sending testfileFinished": {
"state": "pending",
},
},
"4-third.test.ts": {
"third test": {
"state": "passed",
},
},
}
`)
// Crashing worker should not interfere with other test-run, coverage should be reported:
const coverageMap = await readCoverageMap(resolve(root, 'coverage/coverage-final.json'))
const fileCoverage = coverageMap.fileCoverageFor('<process-cwd>/fixtures/pool-worker-exit/src.ts')
expect(fileCoverage.toSummary().functions).toMatchInlineSnapshot(`
{
"covered": 1,
"pct": 50,
"skipped": 0,
"total": 2,
}
`)
})

... where stderr (or buildTree or was it buildError?) is asserted to contain the signals and exit code.

@AriPerkkio AriPerkkio changed the title fix: expose process exit code and signal in unexpected worker exit error fix(pool): expose exit code and signal in unexpected worker exit error Jun 13, 2026
@filmaj

filmaj commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback and guidance @AriPerkkio! I have integrated your optional-code suggestion and was able to add a test to the test file you pointed to - very helpful, thanks. I validated at least this particular pool-worker-exit.test.ts passes locally without issue. I added a new test fixture file to forcibly process.exit the test with a large code to be able to assert on it, and changed an existing crash-test fixture file's signal to kill itself with SIGINT to assert on that as well. Let me know what you think.

@filmaj
filmaj requested a review from AriPerkkio June 13, 2026 13:07
@netlify

netlify Bot commented Jun 15, 2026

Copy link
Copy Markdown

Deploy Preview for vitest-dev ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit b8cbc36
🔍 Latest deploy log https://app.netlify.com/projects/vitest-dev/deploys/6a391f37d7bc6c0008540cab
😎 Deploy Preview https://deploy-preview-10587--vitest-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@filmaj
filmaj force-pushed the raise-code-signal branch from aa09561 to cbac567 Compare June 16, 2026 11:53

@AriPerkkio AriPerkkio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, one small additional improvement to make the error more detailed.

Comment thread test/e2e/test/pool-worker-exit.test.ts Outdated
@filmaj
filmaj requested a review from AriPerkkio June 17, 2026 15:04
Comment thread test/e2e/fixtures/pool-worker-exit/5-exit.test.ts Outdated
@AriPerkkio AriPerkkio changed the title fix(pool): expose exit code and signal in unexpected worker exit error fix(pool): improve error message when worker exits unexpectedly Jun 22, 2026

@AriPerkkio AriPerkkio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks! 💯

@AriPerkkio
AriPerkkio merged commit 76139c5 into vitest-dev:main Jun 22, 2026
14 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants