Skip to content
This repository has been archived by the owner on Oct 2, 2021. It is now read-only.

Support source mapping of stack traces in the Debug Console #6 #190

Merged
merged 5 commits into from
Mar 23, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
35 changes: 31 additions & 4 deletions src/chrome/chromeDebugAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -740,10 +740,37 @@ export abstract class ChromeDebugAdapter implements IDebugAdapter {

protected onExceptionThrown(params: Crdp.Runtime.ExceptionThrownEvent): void {
const formattedException = formatExceptionDetails(params.exceptionDetails);
this._session.sendEvent(new OutputEvent(
formattedException,
'stderr'
));
this.mapFormattedException(formattedException).then(formattedException => {
this._session.sendEvent(new OutputEvent(
formattedException,
'stderr'
));
});
}

// We parse stack trace from `formattedException`, source map it and return a new string
protected async mapFormattedException(formattedException: string): Promise<string> {
const exceptionLines = formattedException.split(/\r?\n/);

for (let i = 0, len = exceptionLines.length; i < len; ++i) {
const line = exceptionLines[i];
const matches = line.match(/^\s+at (.*?)\s*\(?([^ ]+\.js):(\d+):(\d+)\)?$/);

if (matches) {
const fnName = matches[1];
const path = matches[2];
const lineNum = parseInt(matches[3]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TSLint failes due to missing radex param.

const columnNum = parseInt(matches[4]);
const clientPath = this._pathTransformer.getClientPathFromTargetPath(path);
const mapped = await this._sourceMapTransformer.mapToAuthored(clientPath, lineNum, columnNum);

if (mapped) {
exceptionLines[i] = ` at ${fnName ? fnName + ' ': ''}(${mapped.source}:${mapped.line}:${mapped.column})`;
}
}
}

return exceptionLines.join('\n');
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/chrome/consoleHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ function stackTraceToString(stackTrace: Crdp.Runtime.StackTrace): string {
.map(frame => {
const fnName = frame.functionName || (frame.url ? '(anonymous)' : '(eval)');
const fileName = frame.url ? url.parse(frame.url).pathname : 'eval';
return ` at ${fnName} (${fileName}:${frame.lineNumber})`;
return ` at ${fnName} (${fileName}:${frame.lineNumber}:${frame.columnNumber})`;
})
.join('\n');
}
Expand Down
28 changes: 28 additions & 0 deletions test/chrome/chromeDebugAdapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,34 @@ suite('ChromeDebugAdapter', () => {
});
});

suite('onExceptionThrown', () => {
test('exceptions are source mapped when shown in console', async () => {
await chromeDebugAdapter.attach(ATTACH_ARGS);
mockEventEmitter.emit('Runtime.exceptionThrown', <Crdp.Runtime.ExceptionThrownEvent>{
"timestamp": 1490164925297.7559,
"exceptionDetails": {
"exceptionId": 21,
"text": "Uncaught",
"lineNumber": 5,
"columnNumber": 10,
"url": "http://localhost:9999/error.js",
"stackTrace": {},
"exception": {
"type": "object",
"subtype": "error",
"className": "Error",
"description": "Error: kaboom!\n at error (http://localhost:9999/error.js:6:11)\n at some (http://localhost:9999/error.js:4:33)\n at up (http://localhost:9999/error.js:3:31)\n at blow (http://localhost:9999/error.js:2:33)\n at boom (http://localhost:9999/error.js:1:33)\n at http://localhost:9999/error.js:8:1",
"objectId": "{\"injectedScriptId\":148,\"id\":1}"
},
"executionContextId": 148
}
});

//TODO - Test mapped exception

});
});

suite('setExceptionBreakpoints()', () => { });
suite('stepping', () => { });
suite('stackTrace()', () => { });
Expand Down
4 changes: 2 additions & 2 deletions test/chrome/consoleHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ suite('ConsoleHelper', () => {

suite('console.assert()', () => {
test(`Prints params and doesn't resolve format specifiers`, () => {
doAssertForString(Runtime.makeAssert('Fail %s 123', 456), 'Assertion failed: Fail %s 123 456\n at myFn (/script/a.js:4)', true);
doAssertForString(Runtime.makeAssert('Fail %s 123', 456), 'Assertion failed: Fail %s 123 456\n at myFn (/script/a.js:4:1)', true);
});
});
});
Expand Down Expand Up @@ -162,7 +162,7 @@ namespace Runtime {

export function makeAssert(...args: any[]): Crdp.Runtime.ConsoleAPICalledEvent {
const fakeStackTrace: Crdp.Runtime.StackTrace = {
callFrames: [{ url: '/script/a.js', lineNumber: 4, columnNumber: 0, scriptId: '1', functionName: 'myFn' }]
callFrames: [{ url: '/script/a.js', lineNumber: 4, columnNumber: 1, scriptId: '1', functionName: 'myFn' }]
};
return makeMockMessage('assert', args, { level: 'error', stackTrace: fakeStackTrace });
}
Expand Down