diff --git a/packages/vitest/src/node/error.ts b/packages/vitest/src/node/error.ts index 4e54e32fb1db..91f694924629 100644 --- a/packages/vitest/src/node/error.ts +++ b/packages/vitest/src/node/error.ts @@ -26,6 +26,7 @@ interface PrintErrorOptions { logger: Logger fullStack?: boolean showCodeFrame?: boolean + printProperties?: boolean } interface PrintErrorResult { @@ -57,7 +58,7 @@ export function printError( project: WorkspaceProject | undefined, options: PrintErrorOptions, ): PrintErrorResult | undefined { - const { showCodeFrame = true, fullStack = false, type } = options + const { showCodeFrame = true, fullStack = false, type, printProperties = true } = options const logger = options.logger let e = error as ErrorWithDiff @@ -109,7 +110,9 @@ export function printError( } }) - const errorProperties = getErrorProperties(e) + const errorProperties = printProperties + ? getErrorProperties(e) + : {} if (type) { printErrorType(type, project.ctx) @@ -350,14 +353,21 @@ export function printStack( if (stack.length) { logger.error() } - const hasProperties = Object.keys(errorProperties).length > 0 - if (hasProperties) { + if (hasProperties(errorProperties)) { logger.error(c.red(c.dim(divider()))) const propertiesString = inspect(errorProperties) logger.error(c.red(c.bold('Serialized Error:')), c.gray(propertiesString)) } } +function hasProperties(obj: any) { + // eslint-disable-next-line no-unreachable-loop + for (const _key in obj) { + return true + } + return false +} + export function generateCodeFrame( source: string, indent = 0, diff --git a/packages/vitest/src/node/logger.ts b/packages/vitest/src/node/logger.ts index 33355e39b0e7..a3c496b0056c 100644 --- a/packages/vitest/src/node/logger.ts +++ b/packages/vitest/src/node/logger.ts @@ -16,6 +16,7 @@ interface ErrorOptions { type?: string fullStack?: boolean project?: WorkspaceProject + verbose?: boolean } const ESC = '\x1B[' @@ -89,8 +90,7 @@ export class Logger { printError(err: unknown, options: ErrorOptions = {}) { const { fullStack = false, type } = options - const project - = options.project + const project = options.project ?? this.ctx.getCoreWorkspaceProject() ?? this.ctx.projects[0] printError(err, project, { @@ -98,6 +98,7 @@ export class Logger { type, showCodeFrame: true, logger: this, + printProperties: options.verbose, }) } diff --git a/packages/vitest/src/node/reporters/base.ts b/packages/vitest/src/node/reporters/base.ts index 631091281232..05a0ee8b28a4 100644 --- a/packages/vitest/src/node/reporters/base.ts +++ b/packages/vitest/src/node/reporters/base.ts @@ -65,6 +65,8 @@ export abstract class BaseReporter implements Reporter { isTTY: boolean ctx: Vitest = undefined! + protected verbose = false + private _filesInWatchMode = new Map() private _lastRunTimeout = 0 private _lastRunTimer: NodeJS.Timer | undefined @@ -601,7 +603,7 @@ export abstract class BaseReporter implements Reporter { ) } const project = this.ctx.getProjectByTaskId(tasks[0].id) - this.ctx.logger.printError(error, { project }) + this.ctx.logger.printError(error, { project, verbose: this.verbose }) errorDivider() } } diff --git a/packages/vitest/src/node/reporters/verbose.ts b/packages/vitest/src/node/reporters/verbose.ts index 388747e4abf7..189834f8b46e 100644 --- a/packages/vitest/src/node/reporters/verbose.ts +++ b/packages/vitest/src/node/reporters/verbose.ts @@ -6,6 +6,8 @@ import { DefaultReporter } from './default' import { formatProjectName, getStateSymbol } from './renderers/utils' export class VerboseReporter extends DefaultReporter { + protected verbose = true + constructor() { super() this.rendererOptions.renderSucceed = true diff --git a/test/reporters/fixtures/error-props/basic.test.ts b/test/reporters/fixtures/error-props/basic.test.ts new file mode 100644 index 000000000000..05922eee80be --- /dev/null +++ b/test/reporters/fixtures/error-props/basic.test.ts @@ -0,0 +1,11 @@ +import { test } from 'vitest'; + +test('throws', () => { + const error = new Error('error with properties') + Object.assign(error, { + code: 404, + status: 'not found', + }) + throw error +}); + diff --git a/test/reporters/tests/default.test.ts b/test/reporters/tests/default.test.ts index 8b958237d54e..0ae8fa338995 100644 --- a/test/reporters/tests/default.test.ts +++ b/test/reporters/tests/default.test.ts @@ -57,4 +57,15 @@ describe('default reporter', async () => { expect(vitest.stdout).not.toContain('✓ b1 test') expect(vitest.stdout).not.toContain('✓ b2 test') }) + + test('doesn\'t print error properties', async () => { + const result = await runVitest({ + root: 'fixtures/error-props', + reporters: 'default', + env: { CI: '1' }, + }) + + expect(result.stderr).not.toContain(`Serialized Error`) + expect(result.stderr).not.toContain(`status: 'not found'`) + }) }, 120000) diff --git a/test/reporters/tests/verbose.test.ts b/test/reporters/tests/verbose.test.ts index 91fc9d34f2eb..59e08dff6b4c 100644 --- a/test/reporters/tests/verbose.test.ts +++ b/test/reporters/tests/verbose.test.ts @@ -14,3 +14,13 @@ test('duration', async () => { ✓ basic.test.ts > slow [...]ms `) }) + +test('prints error properties', async () => { + const result = await runVitest({ + root: 'fixtures/error-props', + reporters: 'verbose', + env: { CI: '1' }, + }) + + expect(result.stderr).toContain(`Serialized Error: { code: 404, status: 'not found' }`) +})