Source code

Revision control

Copy as Markdown

Other Tools

// Returns the stack trace of an Error, but without the extra boilerplate at the bottom
// (e.g. RunCaseSpecific, processTicksAndRejections, etc.), for logging.
export function extractImportantStackTrace(e: Error): string {
let stack = e.stack;
if (!stack) {
return '';
}
const redundantMessage = 'Error: ' + e.message + '\n';
if (stack.startsWith(redundantMessage)) {
stack = stack.substring(redundantMessage.length);
}
const lines = stack.split('\n');
for (let i = lines.length - 1; i >= 0; --i) {
const line = lines[i];
if (line.indexOf('.spec.') !== -1) {
return lines.slice(0, i + 1).join('\n');
}
}
return stack;
}
// *** Examples ***
//
// Node fail()
// > Error:
// > at CaseRecorder.fail (/Users/kainino/src/cts/src/common/framework/logger.ts:99:30)
// > at RunCaseSpecific.exports.g.test.t [as fn] (/Users/kainino/src/cts/src/unittests/logger.spec.ts:80:7)
// x at RunCaseSpecific.run (/Users/kainino/src/cts/src/common/framework/test_group.ts:121:18)
// x at processTicksAndRejections (internal/process/task_queues.js:86:5)
//
// Node throw
// > Error: hello
// > at RunCaseSpecific.g.test.t [as fn] (/Users/kainino/src/cts/src/unittests/test_group.spec.ts:51:11)
// x at RunCaseSpecific.run (/Users/kainino/src/cts/src/common/framework/test_group.ts:121:18)
// x at processTicksAndRejections (internal/process/task_queues.js:86:5)
//
// Firefox fail()
//
// Firefox throw
//
// Safari fail()
// x asyncFunctionResume@[native code]
// x [native code]
// x promiseReactionJob@[native code]
//
// Safari throw
// x asyncFunctionResume@[native code]
// x [native code]
// x promiseReactionJob@[native code]
//
// Chrome fail()
// x Error
//
// Chrome throw
// x Error: hello
// x at async Promise.all (index 0)
// x at async RunCaseSpecific.run (http://localhost:8080/out/framework/test_group.js:119:7)