Skip to content

Commit 6259abe

Browse files
committed
chore: create a console formatter classs
1 parent 6854d47 commit 6259abe

5 files changed

Lines changed: 154 additions & 183 deletions

File tree

src/McpResponse.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
*/
66

77
import {createStackTraceForConsoleMessage} from './DevtoolsUtils.js';
8-
import type {ConsoleMessageData} from './formatters/consoleFormatter.js';
98
import {
10-
formatConsoleEventShort,
11-
formatConsoleEventVerbose,
12-
} from './formatters/consoleFormatter.js';
9+
ConsoleFormatter,
10+
type ConsoleMessageData,
11+
} from './formatters/ConsoleFormatter.js';
1312
import {IssueFormatter} from './formatters/IssueFormatter.js';
1413
import {NetworkFormatter} from './formatters/NetworkFormatter.js';
1514
import {SnapshotFormatter} from './formatters/SnapshotFormatter.js';
@@ -234,7 +233,7 @@ export class McpResponse implements Response {
234233
detailedNetworkRequest = formatter;
235234
}
236235

237-
let consoleData: ConsoleMessageData | IssueFormatter | undefined;
236+
let consoleData: ConsoleFormatter | IssueFormatter | undefined;
238237

239238
if (this.#attachedConsoleMessageId) {
240239
const message = context.getConsoleMessageById(
@@ -248,7 +247,7 @@ export class McpResponse implements Response {
248247
? await createStackTraceForConsoleMessage(devTools, consoleMessage)
249248
: undefined;
250249

251-
consoleData = {
250+
consoleData = new ConsoleFormatter({
252251
consoleMessageStableId,
253252
type: consoleMessage.type(),
254253
message: consoleMessage.text(),
@@ -263,7 +262,7 @@ export class McpResponse implements Response {
263262
}),
264263
),
265264
stackTrace,
266-
};
265+
});
267266
} else if (message instanceof DevTools.AggregatedIssue) {
268267
const formatter = new IssueFormatter(message, {
269268
id: consoleMessageStableId,
@@ -277,16 +276,16 @@ export class McpResponse implements Response {
277276
}
278277
consoleData = formatter;
279278
} else {
280-
consoleData = {
279+
consoleData = new ConsoleFormatter({
281280
consoleMessageStableId,
282281
type: 'error',
283282
message: (message as Error).message,
284283
args: [],
285-
};
284+
});
286285
}
287286
}
288287

289-
let consoleListData: Array<ConsoleMessageData | IssueFormatter> | undefined;
288+
let consoleListData: Array<ConsoleFormatter | IssueFormatter> | undefined;
290289
if (this.#consoleDataOptions?.include) {
291290
let messages = context.getConsoleData(
292291
this.#consoleDataOptions.includePreservedMessages,
@@ -310,7 +309,7 @@ export class McpResponse implements Response {
310309
messages.map(
311310
async (
312311
item,
313-
): Promise<ConsoleMessageData | IssueFormatter | null> => {
312+
): Promise<ConsoleFormatter | IssueFormatter | null> => {
314313
const consoleMessageStableId =
315314
context.getConsoleMessageStableId(item);
316315
if ('args' in item) {
@@ -322,7 +321,7 @@ export class McpResponse implements Response {
322321
consoleMessage,
323322
)
324323
: undefined;
325-
return {
324+
return new ConsoleFormatter({
326325
consoleMessageStableId,
327326
type: consoleMessage.type(),
328327
message: consoleMessage.text(),
@@ -337,7 +336,7 @@ export class McpResponse implements Response {
337336
}),
338337
),
339338
stackTrace,
340-
};
339+
});
341340
}
342341
if (item instanceof DevTools.AggregatedIssue) {
343342
const formatter = new IssueFormatter(item, {
@@ -348,12 +347,12 @@ export class McpResponse implements Response {
348347
}
349348
return formatter;
350349
}
351-
return {
350+
return new ConsoleFormatter({
352351
consoleMessageStableId,
353352
type: 'error',
354353
message: (item as Error).message,
355354
args: [],
356-
};
355+
});
357356
},
358357
),
359358
)
@@ -411,8 +410,8 @@ export class McpResponse implements Response {
411410
toolName: string,
412411
context: McpContext,
413412
data: {
414-
consoleData: ConsoleMessageData | IssueFormatter | undefined;
415-
consoleListData: Array<ConsoleMessageData | IssueFormatter> | undefined;
413+
consoleData: ConsoleFormatter | IssueFormatter | undefined;
414+
consoleListData: Array<ConsoleFormatter | IssueFormatter> | undefined;
416415
snapshot: SnapshotFormatter | string | undefined;
417416
detailedNetworkRequest?: NetworkFormatter;
418417
networkRequests?: NetworkFormatter[];
@@ -551,7 +550,7 @@ Call ${handleDialog.name} to handle it before continuing.`);
551550
if (message instanceof IssueFormatter) {
552551
return message.toString();
553552
}
554-
return formatConsoleEventShort(message);
553+
return message.toString();
555554
}),
556555
);
557556
} else {
@@ -604,7 +603,7 @@ Call ${handleDialog.name} to handle it before continuing.`);
604603

605604
#formatConsoleData(
606605
context: McpContext,
607-
data: ConsoleMessageData | IssueFormatter | undefined,
606+
data: ConsoleFormatter | IssueFormatter | undefined,
608607
): string[] {
609608
const response: string[] = [];
610609
if (!data) {
@@ -614,7 +613,7 @@ Call ${handleDialog.name} to handle it before continuing.`);
614613
if (data instanceof IssueFormatter) {
615614
response.push(data.toStringDetailed());
616615
} else {
617-
response.push(formatConsoleEventVerbose(data, context));
616+
response.push(data.toStringDetailed());
618617
}
619618
return response;
620619
}

src/formatters/ConsoleFormatter.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/**
2+
* @license
3+
* Copyright 2025 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import type {DevTools} from '../third_party/index.js';
8+
9+
export interface ConsoleMessageData {
10+
consoleMessageStableId: number;
11+
type?: string;
12+
item?: DevTools.AggregatedIssue;
13+
message?: string;
14+
count?: number;
15+
description?: string;
16+
args?: string[];
17+
stackTrace?: DevTools.StackTrace.StackTrace.StackTrace;
18+
}
19+
20+
export class ConsoleFormatter {
21+
#msg: ConsoleMessageData;
22+
23+
constructor(msg: ConsoleMessageData) {
24+
this.#msg = msg;
25+
}
26+
27+
// The short format for a console message.
28+
toString(): string {
29+
return `msgid=${this.#msg.consoleMessageStableId} [${this.#msg.type}] ${this.#msg.message} (${this.#msg.args?.length ?? 0} args)`;
30+
}
31+
32+
// The verbose format for a console message, including all details.
33+
toStringDetailed(): string {
34+
const result = [
35+
`ID: ${this.#msg.consoleMessageStableId}`,
36+
`Message: ${this.#msg.type}> ${this.#msg.message}`,
37+
this.#formatArgs(),
38+
this.#formatStackTrace(this.#msg.stackTrace),
39+
].filter(line => !!line);
40+
return result.join('\n');
41+
}
42+
43+
#getArgs() {
44+
const args = [...(this.#msg.args ?? [])];
45+
46+
// If there is no text, the first argument serves as text (see formatMessage).
47+
if (!this.#msg.message) {
48+
args.shift();
49+
}
50+
51+
return args;
52+
}
53+
54+
#formatArg(arg: unknown) {
55+
return typeof arg === 'object' ? JSON.stringify(arg) : String(arg);
56+
}
57+
58+
#formatArgs(): string {
59+
const args = this.#getArgs();
60+
61+
if (!args.length) {
62+
return '';
63+
}
64+
65+
const result = ['### Arguments'];
66+
67+
for (const [key, arg] of args.entries()) {
68+
result.push(`Arg #${key}: ${this.#formatArg(arg)}`);
69+
}
70+
71+
return result.join('\n');
72+
}
73+
74+
#formatStackTrace(
75+
stackTrace: DevTools.StackTrace.StackTrace.StackTrace | undefined,
76+
): string {
77+
if (!stackTrace) {
78+
return '';
79+
}
80+
81+
return [
82+
'### Stack trace',
83+
this.#formatFragment(stackTrace.syncFragment),
84+
...stackTrace.asyncFragments.map(this.#formatAsyncFragment.bind(this)),
85+
].join('\n');
86+
}
87+
88+
#formatFragment(
89+
fragment: DevTools.StackTrace.StackTrace.Fragment,
90+
): string {
91+
return fragment.frames.map(this.#formatFrame).join('\n');
92+
}
93+
94+
#formatAsyncFragment(
95+
fragment: DevTools.StackTrace.StackTrace.AsyncFragment,
96+
): string {
97+
const separatorLineLength = 40;
98+
const prefix = `--- ${fragment.description || 'async'} `;
99+
const separator = prefix + '-'.repeat(separatorLineLength - prefix.length);
100+
return separator + '\n' + this.#formatFragment(fragment);
101+
}
102+
103+
#formatFrame(frame: DevTools.StackTrace.StackTrace.Frame): string {
104+
let result = `at ${frame.name ?? '<anonymous>'}`;
105+
if (frame.uiSourceCode) {
106+
result += ` (${frame.uiSourceCode.displayName()}:${frame.line}:${frame.column})`;
107+
} else if (frame.url) {
108+
result += ` (${frame.url}:${frame.line}:${frame.column})`;
109+
}
110+
return result;
111+
}
112+
}

src/formatters/consoleFormatter.ts

Lines changed: 0 additions & 129 deletions
This file was deleted.

0 commit comments

Comments
 (0)