From d28cbf09780c6643e1c94f959907dfddb0a3beeb Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sat, 21 May 2022 21:21:23 +0900 Subject: [PATCH 1/4] fix: handle error from pool.run --- packages/vitest/src/node/pool.ts | 27 +++++++++++++++++++-------- packages/vitest/src/utils/index.ts | 11 +++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/packages/vitest/src/node/pool.ts b/packages/vitest/src/node/pool.ts index 19b3b37a907e..cdfc72bd89f6 100644 --- a/packages/vitest/src/node/pool.ts +++ b/packages/vitest/src/node/pool.ts @@ -9,6 +9,7 @@ import type { RawSourceMap } from 'vite-node' import type { WorkerContext, WorkerRPC } from '../types' import { distDir } from '../constants' import type { Vitest } from './core' +import { AggregateError } from '../utils' export type RunWithFiles = (files: string[], invalidates?: string[]) => Promise @@ -41,10 +42,12 @@ export function createFakePool(ctx: Vitest): WorkerPool { id: 1, } - await worker[name](data, { transferList: [workerPort] }) - - port.close() - workerPort.close() + try { + await worker[name](data, { transferList: [workerPort] }) + } finally { + port.close() + workerPort.close() + } } } @@ -80,7 +83,7 @@ export function createWorkerPool(ctx: Vitest): WorkerPool { return async (files, invalidates) => { let id = 0 const config = ctx.getSerializableConfig() - await Promise.all(files.map(async (file) => { + const results = await Promise.allSettled(files.map(async (file) => { const { workerPort, port } = createChannel(ctx) const data: WorkerContext = { @@ -91,10 +94,18 @@ export function createWorkerPool(ctx: Vitest): WorkerPool { id: ++id, } - await pool.run(data, { transferList: [workerPort], name }) - port.close() - workerPort.close() + try { + await pool.run(data, { transferList: [workerPort], name }) + } finally { + port.close() + workerPort.close() + } })) + + const errors = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected').map(r => r.reason) + if (errors.length > 0) { + throw new AggregateError(errors) + } } } diff --git a/packages/vitest/src/utils/index.ts b/packages/vitest/src/utils/index.ts index 1765ccdf7f64..1fc7e5d65022 100644 --- a/packages/vitest/src/utils/index.ts +++ b/packages/vitest/src/utils/index.ts @@ -129,3 +129,14 @@ export function getCallLastIndex(code: string) { } export { resolve as resolvePath } + +class AggregateErrorPonyfill extends Error { + errors: unknown[] + constructor(errors: Iterable, message = '') { + super(message) + this.errors = [...errors] + } +} + +// AggregateError is supported in Node.js 15.0.0+ +export const AggregateError = global.AggregateError || AggregateErrorPonyfill From a23fb585df1c20407842ac938ba371250087954e Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sat, 21 May 2022 21:44:55 +0900 Subject: [PATCH 2/4] chore: lint fix --- packages/vitest/src/node/pool.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/vitest/src/node/pool.ts b/packages/vitest/src/node/pool.ts index cdfc72bd89f6..fc7f492ad9f2 100644 --- a/packages/vitest/src/node/pool.ts +++ b/packages/vitest/src/node/pool.ts @@ -8,8 +8,8 @@ import { createBirpc } from 'birpc' import type { RawSourceMap } from 'vite-node' import type { WorkerContext, WorkerRPC } from '../types' import { distDir } from '../constants' -import type { Vitest } from './core' import { AggregateError } from '../utils' +import type { Vitest } from './core' export type RunWithFiles = (files: string[], invalidates?: string[]) => Promise @@ -44,7 +44,8 @@ export function createFakePool(ctx: Vitest): WorkerPool { try { await worker[name](data, { transferList: [workerPort] }) - } finally { + } + finally { port.close() workerPort.close() } @@ -96,16 +97,16 @@ export function createWorkerPool(ctx: Vitest): WorkerPool { try { await pool.run(data, { transferList: [workerPort], name }) - } finally { + } + finally { port.close() workerPort.close() } })) const errors = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected').map(r => r.reason) - if (errors.length > 0) { + if (errors.length > 0) throw new AggregateError(errors) - } } } From 0ab3996d3051ed31755b7fa2f0354f1e2177f8bc Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sat, 21 May 2022 22:54:34 +0900 Subject: [PATCH 3/4] chore: update aggregate error message --- packages/vitest/src/node/pool.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vitest/src/node/pool.ts b/packages/vitest/src/node/pool.ts index fc7f492ad9f2..a542178e27e1 100644 --- a/packages/vitest/src/node/pool.ts +++ b/packages/vitest/src/node/pool.ts @@ -106,7 +106,7 @@ export function createWorkerPool(ctx: Vitest): WorkerPool { const errors = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected').map(r => r.reason) if (errors.length > 0) - throw new AggregateError(errors) + throw new AggregateError(errors, 'Errors occurred while running tests. For more information, see serialized error.') } } From 7478246ca3e4b289ee2a54ff6d23a706f460b314 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Sat, 21 May 2022 23:04:44 +0900 Subject: [PATCH 4/4] chore: use AggregateErrorPonyfill consistently --- packages/vitest/src/utils/index.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/vitest/src/utils/index.ts b/packages/vitest/src/utils/index.ts index 1fc7e5d65022..799340c7e329 100644 --- a/packages/vitest/src/utils/index.ts +++ b/packages/vitest/src/utils/index.ts @@ -130,6 +130,7 @@ export function getCallLastIndex(code: string) { export { resolve as resolvePath } +// AggregateError is supported in Node.js 15.0.0+ class AggregateErrorPonyfill extends Error { errors: unknown[] constructor(errors: Iterable, message = '') { @@ -137,6 +138,4 @@ class AggregateErrorPonyfill extends Error { this.errors = [...errors] } } - -// AggregateError is supported in Node.js 15.0.0+ -export const AggregateError = global.AggregateError || AggregateErrorPonyfill +export { AggregateErrorPonyfill as AggregateError }