Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/DevtoolsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,14 @@ export class SymbolizedError {
}
return details.text;
}

static createForTesting(
message: string,
stackTrace?: DevTools.StackTrace.StackTrace.StackTrace,
cause?: SymbolizedError,
) {
return new SymbolizedError(message, stackTrace, cause);
}
}

export async function createStackTraceForConsoleMessage(
Expand Down
12 changes: 11 additions & 1 deletion src/formatters/ConsoleFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ export class ConsoleFormatter {
}

#formatArg(arg: unknown) {
if (arg instanceof SymbolizedError) {
return [
arg.message,
this.#formatStackTrace(arg.stackTrace, /* includeHeading */ false),
]
.filter(line => !!line)
.join('\n');
}
return typeof arg === 'object' ? JSON.stringify(arg) : String(arg);
}

Expand All @@ -157,13 +165,15 @@ export class ConsoleFormatter {

#formatStackTrace(
stackTrace: DevTools.DevTools.StackTrace.StackTrace.StackTrace | undefined,
includeHeading = true,
): string {
if (!stackTrace) {
return '';
}

const heading = includeHeading ? ['### Stack trace'] : [];
return [
'### Stack trace',
...heading,
this.#formatFragment(stackTrace.syncFragment),
...stackTrace.asyncFragments.map(this.#formatAsyncFragment.bind(this)),
'Note: line and column numbers use 1-based indexing',
Expand Down
10 changes: 10 additions & 0 deletions tests/formatters/ConsoleFormatter.test.js.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ at schedule (util.ts:5:2)
Note: line and column numbers use 1-based indexing
`;

exports[`ConsoleFormatter > toStringDetailed > formats a console message with an Error object argument 1`] = `
ID: 8
Message: log> JSHandle@error
### Arguments
Arg #0: TypeError: Cannot read properties of undefined
at foo (foo.ts:10:2)
at bar (foo.ts:20:2)
Note: line and column numbers use 1-based indexing
`;

exports[`ConsoleFormatter > toStringDetailed > formats a console.error message 1`] = `
ID: 4
Message: error> Something went wrong
Expand Down
39 changes: 39 additions & 0 deletions tests/formatters/ConsoleFormatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import assert from 'node:assert';
import {describe, it} from 'node:test';

import {SymbolizedError} from '../../src/DevtoolsUtils.js';
import {ConsoleFormatter} from '../../src/formatters/ConsoleFormatter.js';
import {UncaughtError} from '../../src/PageCollector.js';
import type {ConsoleMessage} from '../../src/third_party/index.js';
Expand Down Expand Up @@ -260,6 +261,44 @@ describe('ConsoleFormatter', () => {
).toStringDetailed();
t.assert.snapshot?.(result);
});

it('formats a console message with an Error object argument', async t => {
const message = createMockMessage({
type: () => 'log',
text: () => 'JSHandle@error',
});
const stackTrace = {
syncFragment: {
frames: [
{
line: 10,
column: 2,
url: 'foo.ts',
name: 'foo',
},
{
line: 20,
column: 2,
url: 'foo.ts',
name: 'bar',
},
],
},
asyncFragments: [],
} as unknown as DevTools.StackTrace.StackTrace.StackTrace;
const error = SymbolizedError.createForTesting(
'TypeError: Cannot read properties of undefined',
stackTrace,
);

const result = (
await ConsoleFormatter.from(message, {
id: 8,
resolvedArgsForTesting: [error],
})
).toStringDetailed();
t.assert.snapshot?.(result);
});
});
describe('toJSON', () => {
it('formats a console.log message', async () => {
Expand Down