[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

feat: add `logger.formatError` (#10268)

Co-authored-by: Codex <noreply@openai.com>

authored by

Hiroshi Ogawa
Codex
and committed by
GitHub
(May 5, 2026, 10:47 AM +0100) 2c5f3ee2 d22b029a

+19 -18
+6 -3
packages/vitest/src/node/logger.ts
··· 1 - import type { Task } from '@vitest/runner' 2 1 import type { Writable } from 'node:stream' 3 2 import type { TypeCheckError } from '../typecheck/typechecker' 4 3 import type { Vitest } from './core' 4 + import type { CapturePrintErrorResult } from './printError' 5 5 import type { TestProject } from './project' 6 6 import { Console } from 'node:console' 7 7 import { toArray } from '@vitest/utils/helpers' 8 8 import c from 'tinyrainbow' 9 9 import { highlightCode } from '../utils/colors' 10 - import { printError } from './printError' 10 + import { capturePrintError, printError } from './printError' 11 11 import { divider, errorBanner, formatProjectName, withLabel } from './reporters/renderers/utils' 12 12 import { RandomSequencer } from './sequencers/RandomSequencer' 13 13 ··· 17 17 project?: TestProject 18 18 verbose?: boolean 19 19 screenshotPaths?: string[] 20 - task?: Task 21 20 showCodeFrame?: boolean 22 21 } 23 22 ··· 107 106 108 107 printError(err: unknown, options: ErrorOptions = {}): void { 109 108 printError(err, this.ctx, this, options) 109 + } 110 + 111 + formatError(err: unknown, options: ErrorOptions = {}): CapturePrintErrorResult { 112 + return capturePrintError(err, this.ctx, options) 110 113 } 111 114 112 115 deprecate(message: string): void {
+7 -2
packages/vitest/src/node/printError.ts
··· 36 36 nearest?: ParsedStack 37 37 } 38 38 39 + export interface CapturePrintErrorResult { 40 + nearest: ParsedStack | undefined 41 + output: string 42 + } 43 + 39 44 // use Logger with custom Console to capture entire error printing 40 45 export function capturePrintError( 41 46 error: unknown, 42 47 ctx: Vitest, 43 48 options: ErrorOptions, 44 - ): { nearest: ParsedStack | undefined; output: string } { 49 + ): CapturePrintErrorResult { 45 50 let output = '' 46 51 const writable = new Writable({ 47 52 write(chunk, _encoding, callback) { ··· 90 95 91 96 // browser stack trace needs to be processed differently, 92 97 // so there is a separate method for that 93 - if (options.task?.file.pool === 'browser' && project.browser) { 98 + if (project.browser) { 94 99 return project.browser.parseErrorStacktrace(error, { 95 100 frameFilter: project.config.onStackTrace, 96 101 ignoreStackEntries: options.fullStack ? [] : undefined,
-1
packages/vitest/src/node/reporters/base.ts
··· 965 965 project: this.ctx.getProjectByName(tasks[0].file.projectName || ''), 966 966 verbose: this.verbose, 967 967 screenshotPaths, 968 - task: tasks[0], 969 968 }) 970 969 971 970 if (tasks[0].type === 'test' && tasks[0].annotations.length) {
+3 -6
packages/vitest/src/node/reporters/github-actions.ts
··· 1 - import type { File, TestAnnotation } from '@vitest/runner' 1 + import type { TestAnnotation } from '@vitest/runner' 2 2 import type { SerializedError } from '@vitest/utils' 3 3 import type { Vitest } from '../core' 4 4 import type { TestProject } from '../project' ··· 9 9 import { getFullName, getTasks } from '@vitest/runner/utils' 10 10 import { deepMerge } from '@vitest/utils/helpers' 11 11 import { relative } from 'pathe' 12 - import { capturePrintError } from '../printError' 13 12 import { noun } from './renderers/utils' 14 13 15 14 export interface GithubActionsReporterOptions { ··· 127 126 project: TestProject 128 127 title: string 129 128 error: unknown 130 - file?: File 131 129 }>() 132 130 for (const error of errors) { 133 131 projectErrors.push({ ··· 150 148 project, 151 149 title: project.name ? `[${project.name}] ${title}` : title, 152 150 error, 153 - file, 154 151 }) 155 152 } 156 153 } 157 154 } 158 155 159 156 // format errors via `printError` 160 - for (const { project, title, error, file } of projectErrors) { 161 - const result = capturePrintError(error, this.ctx, { project, task: file }) 157 + for (const { project, title, error } of projectErrors) { 158 + const result = this.ctx.logger.formatError(error, { project }) 162 159 const stack = result?.nearest 163 160 if (!stack) { 164 161 continue
+3 -6
packages/vitest/src/node/reporters/junit.ts
··· 9 9 import { getSuites } from '@vitest/runner/utils' 10 10 import { basename, dirname, relative, resolve } from 'pathe' 11 11 import { getOutputFile } from '../../utils/config-helpers' 12 - import { capturePrintError } from '../printError' 13 12 import { IndentedLogger } from './renderers/indented-logger' 14 13 15 14 export interface ClassnameTemplateVariables { ··· 396 395 return 397 396 } 398 397 399 - const result = capturePrintError( 400 - error, 401 - this.ctx, 402 - { project: this.ctx.getProjectByName(task.file?.projectName ?? ''), task }, 403 - ) 398 + const result = this.ctx.logger.formatError(error, { 399 + project: this.ctx.getProjectByName(task.file?.projectName ?? ''), 400 + }) 404 401 await this.baseLog( 405 402 escapeXML(stripVTControlCharacters(result.output.trim())), 406 403 )