@@ -12,6 +12,7 @@ import {
1212import { UncaughtError } from '../PageCollector.js' ;
1313import * as DevTools from '../third_party/index.js' ;
1414import type { ConsoleMessage } from '../third_party/index.js' ;
15+ import { formatConsoleMessage } from '../utils/ConsoleFormat.js' ;
1516
1617export interface ConsoleFormatterOptions {
1718 fetchDetailedData ?: boolean ;
@@ -36,6 +37,7 @@ export class ConsoleFormatter {
3637
3738 readonly #argCount: number ;
3839 readonly #resolvedArgs: unknown [ ] ;
40+ readonly #remainingArgs: unknown [ ] ;
3941
4042 readonly #stack?: DevTools . DevTools . StackTrace . StackTrace . StackTrace ;
4143 readonly #cause?: SymbolizedError ;
@@ -57,6 +59,17 @@ export class ConsoleFormatter {
5759 this . #text = params . text ;
5860 this . #argCount = params . argCount ?? 0 ;
5961 this . #resolvedArgs = params . resolvedArgs ?? [ ] ;
62+
63+ // Calculate remaining arguments after template substitution
64+ if ( this . #resolvedArgs. length > 0 && this . #text) {
65+ const { remainingArgs} = formatConsoleMessage ( this . #text, this . #resolvedArgs) ;
66+ this . #remainingArgs = remainingArgs ;
67+ } else if ( ! this . #text && this . #resolvedArgs. length > 0 ) {
68+ this . #remainingArgs = this . #resolvedArgs. slice ( 1 ) ;
69+ } else {
70+ this . #remainingArgs = this . #resolvedArgs;
71+ }
72+
6073 this . #stack = params . stack ;
6174 this . #cause = params . cause ;
6275 this . #isIgnored = params . isIgnored ;
@@ -112,12 +125,14 @@ export class ConsoleFormatter {
112125 let resolvedArgs : unknown [ ] = [ ] ;
113126 if ( options . resolvedArgsForTesting ) {
114127 resolvedArgs = options . resolvedArgsForTesting ;
115- } else if ( options . fetchDetailedData ) {
128+ } else {
116129 resolvedArgs = await Promise . all (
117130 msg . args ( ) . map ( async ( arg , i ) => {
118131 try {
119132 const remoteObject = arg . remoteObject ( ) ;
120133 if (
134+ options . fetchDetailedData &&
135+ options . devTools &&
121136 remoteObject . type === 'object' &&
122137 remoteObject . subtype === 'error'
123138 ) {
@@ -160,14 +175,14 @@ export class ConsoleFormatter {
160175
161176 // The short format for a console message.
162177 toString ( ) : string {
163- return `msgid=${ this . #id} [${ this . #type} ] ${ this . #text } (${ this . #argCount} args)` ;
178+ return `msgid=${ this . #id} [${ this . #type} ] ${ this . #getFormattedText ( ) } (${ this . #argCount} args)` ;
164179 }
165180
166181 // The verbose format for a console message, including all details.
167182 toStringDetailed ( ) : string {
168183 const result = [
169184 `ID: ${ this . #id} ` ,
170- `Message: ${ this . #type} > ${ this . #text } ` ,
185+ `Message: ${ this . #type} > ${ this . #getFormattedText ( ) } ` ,
171186 this . #formatArgs( ) ,
172187 this . #formatStackTrace( this . #stack, this . #cause, {
173188 includeHeading : true ,
@@ -176,16 +191,22 @@ export class ConsoleFormatter {
176191 return result . join ( '\n' ) ;
177192 }
178193
179- #getArgs ( ) : unknown [ ] {
180- if ( this . #resolvedArgs . length > 0 ) {
181- const args = [ ... this . #resolvedArgs ] ;
182- // If there is no text, the first argument serves as text (see formatMessage).
183- if ( ! this . #text) {
184- args . shift ( ) ;
185- }
186- return args ;
194+ // Gets the formatted message text, applying template string substitutions if arguments are available.
195+ #getFormattedText ( ) : string {
196+ if ( this . #resolvedArgs . length > 0 && this . #text ) {
197+ // apply template formatting
198+ const { formattedText } = formatConsoleMessage ( this . #text, this . #resolvedArgs ) ;
199+ return formattedText ;
200+ } else if ( ! this . #text && this . #resolvedArgs . length > 0 ) {
201+ return this . #formatArg ( this . #resolvedArgs [ 0 ] ) ;
187202 }
188- return [ ] ;
203+ // return the raw text
204+ return this . #text;
205+ }
206+
207+ #getArgs( ) : unknown [ ] {
208+ // Return the remaining arguments after template substitution
209+ return this . #remainingArgs;
189210 }
190211
191212 #formatArg( arg : unknown ) {
0 commit comments