diff --git a/packages/coverage-v8/src/provider.ts b/packages/coverage-v8/src/provider.ts index ca038ed47902..bce56a1210b3 100644 --- a/packages/coverage-v8/src/provider.ts +++ b/packages/coverage-v8/src/provider.ts @@ -543,7 +543,13 @@ export class V8CoverageProvider extends BaseCoverageProvider implements Coverage ) await converter.load() - converter.applyCoverage(functions) + try { + converter.applyCoverage(functions) + } + catch (error) { + this.ctx.logger.error(`Failed to convert coverage for ${url}.\n`, error) + } + coverageMap.merge(converter.toIstanbul()) }), ) diff --git a/test/coverage-test/fixtures/src/cjs-package/entry.js b/test/coverage-test/fixtures/src/cjs-package/entry.js new file mode 100644 index 000000000000..883382e4e68e --- /dev/null +++ b/test/coverage-test/fixtures/src/cjs-package/entry.js @@ -0,0 +1,2 @@ +require("./target"); +module.exports = "Entry here" \ No newline at end of file diff --git a/test/coverage-test/fixtures/src/cjs-package/package.json b/test/coverage-test/fixtures/src/cjs-package/package.json new file mode 100644 index 000000000000..d7243077cec0 --- /dev/null +++ b/test/coverage-test/fixtures/src/cjs-package/package.json @@ -0,0 +1,5 @@ +{ + "name": "cjs-package", + "main": "./entry.js", + "type": "commonjs" +} \ No newline at end of file diff --git a/test/coverage-test/fixtures/src/cjs-package/target.js b/test/coverage-test/fixtures/src/cjs-package/target.js new file mode 100644 index 000000000000..8a5e164e4564 --- /dev/null +++ b/test/coverage-test/fixtures/src/cjs-package/target.js @@ -0,0 +1,9 @@ +"use strict"; + +module.exports = { + debug: 0, + info: 1, + warn: 2, + error: 3, + fatal: 4, +}; diff --git a/test/coverage-test/test/convert-failure.v8.test.ts b/test/coverage-test/test/convert-failure.v8.test.ts new file mode 100644 index 000000000000..2776b8d026d9 --- /dev/null +++ b/test/coverage-test/test/convert-failure.v8.test.ts @@ -0,0 +1,40 @@ +import { createRequire } from 'node:module' +import { expect } from 'vitest' +import { coverageTest, normalizeURL, readCoverageMap, runVitest, test } from '../utils' + +test('logs warning but doesn\'t crash when coverage conversion fails', async () => { + const { stderr, exitCode } = await runVitest({ + include: [normalizeURL(import.meta.url)], + coverage: { reporter: 'json', include: ['fixtures/src/**'], all: false }, + }, { throwOnError: false }) + + // Logged warning should not set erroneous exit code + expect(exitCode).toBe(0) + + expect(stderr).toMatch('Failed to convert coverage for file://') + expect(stderr).toMatch('/fixtures/src/cjs-package/target.js.') + expect(stderr).toMatch('TypeError: Cannot read properties of undefined (reading \'endCol\')') + + const coverageMap = await readCoverageMap() + + expect(coverageMap.files()).toMatchInlineSnapshot(` + [ + "/fixtures/src/cjs-package/entry.js", + "/fixtures/src/cjs-package/target.js", + ] + `) +}) + +coverageTest('load file both from Vite and outside it', async () => { + const entry = createRequire(import.meta.url)('../fixtures/src/cjs-package' as any) + const target = await import('../fixtures/src/cjs-package/target.js' as any) + + expect(entry).toBe('Entry here') + expect(target.default).toStrictEqual({ + debug: 0, + error: 3, + fatal: 4, + info: 1, + warn: 2, + }) +})