fix(pool): handle worker start failures gracefully (#9337) · vitest-dev/vitest@200dadb
1+import type { Span } from '@opentelemetry/api'
12import type { ContextTestEnvironment } from '../../types/worker'
23import type { Logger } from '../logger'
34import type { StateManager } from '../state'
@@ -118,21 +119,27 @@ export class Pool {
118119WORKER_START_TIMEOUT,
119120)
120121121-await runner.start({ workerId: task.context.workerId }).finally(() => clearTimeout(id))
122+await runner.start({ workerId: task.context.workerId })
123+.catch(error =>
124+resolver.reject(
125+new Error(`[vitest-pool]: Failed to start ${task.worker} worker for test files ${formatFiles(task)}.`, { cause: error }),
126+),
127+)
128+.finally(() => clearTimeout(id))
122129}
123130124-const span = runner.startTracesSpan(`vitest.worker.${method}`)
125-// Start running the test in the worker
126-runner.request(method, task.context)
131+let span: Span | undefined
132+133+if (!resolver.isRejected) {
134+span = runner.startTracesSpan(`vitest.worker.${method}`)
135+136+// Start running the test in the worker
137+runner.request(method, task.context)
138+}
127139128140await resolver.promise
129-.catch((error) => {
130-span.recordException(error)
131-throw error
132-})
133-.finally(() => {
134-span.end()
135-})
141+.catch(error => span?.recordException(error))
142+.finally(() => span?.end())
136143137144const index = this.activeTasks.indexOf(activeTask)
138145if (index !== -1) {
@@ -158,7 +165,7 @@ export class Pool {
158165)
159166160167this.exitPromises.push(
161-runner.stop()
168+runner.stop({ force: resolver.isRejected })
162169.then(() => clearTimeout(id))
163170.catch(error => this.logger.error(`[vitest-pool]: Failed to terminate ${task.worker} worker for test files ${formatFiles(task)}.`, error)),
164171)
@@ -281,7 +288,17 @@ function withResolvers() {
281288reject = rej
282289})
283290284-return { resolve, reject, promise }
291+const resolver = {
292+ promise,
293+ resolve,
294+reject: (reason: unknown) => {
295+resolver.isRejected = true
296+reject(reason)
297+},
298+isRejected: false,
299+}
300+301+return resolver
285302}
286303287304function formatFiles(task: PoolTask) {