77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import * as path from 'path';
|
|
|
|
export interface Frame {
|
|
functionName?: string;
|
|
fileName: string;
|
|
line?: number;
|
|
column?: number;
|
|
}
|
|
|
|
/** Converts an error into a list of frames based on the error stack */
|
|
export function parse(err: Error): Frame[] {
|
|
if (!err.stack) {
|
|
return [];
|
|
}
|
|
|
|
const lines = err.stack.split('\n').slice(1);
|
|
return lines
|
|
.map(function(line: string): Frame | null {
|
|
if (line.match(/^\s*[-]{4,}$/)) {
|
|
return { fileName: line };
|
|
}
|
|
|
|
let pieces = line.trim().split(' ');
|
|
// pieces[0] will always be 'at'
|
|
function parseData(fileUri: string, functionName?: string): Frame {
|
|
let pieces = fileUri.split(':');
|
|
let column: number | undefined = parseInt(pieces[pieces.length - 1]); if (Number.isNaN(column)) column = undefined;
|
|
let line: number | undefined = parseInt(pieces[pieces.length - 2]); if (Number.isNaN(line)) line = undefined;
|
|
let colLinePieces = (column ? 1 : 0) + (line ? 1 : 0)
|
|
let fileName = pieces.slice(0, pieces.length - colLinePieces).join(':');
|
|
return { fileName: fileName, line: line, column: column, functionName: functionName };
|
|
}
|
|
if (pieces.length === 2) {
|
|
return parseData(pieces[1]);
|
|
} else {
|
|
// chop of parenthesis chop off 'at' and file path
|
|
return parseData(pieces[pieces.length - 1].slice(1, -1), pieces.slice(1, -1).join(' '));
|
|
}
|
|
})
|
|
.filter(function(callSite): boolean {
|
|
return !!callSite;
|
|
}) as Frame[];
|
|
}
|
|
|
|
export function relativizeFilePath(frame: Frame, baseDir: string): Frame {
|
|
if (frame.fileName && frame.fileName[0] === '/') {
|
|
let relativeFileName = path.relative(baseDir, frame.fileName);
|
|
return Object.assign({}, frame, { fileName: relativeFileName });
|
|
}
|
|
return frame;
|
|
}
|
|
|
|
/** Converts a parsed frame into a line that "could have come from an Error" */
|
|
export function getFrameLine(frame: Frame): string {
|
|
if (frame.functionName) {
|
|
if (frame.line) {
|
|
if (frame.column) {
|
|
return ` at ${frame.functionName} (${frame.fileName}:${frame.line}:${frame.column})`;
|
|
} else {
|
|
return ` at ${frame.functionName} (${frame.fileName}:${frame.line})`;
|
|
}
|
|
} else {
|
|
return ` at ${frame.functionName} (${frame.fileName})`;
|
|
}
|
|
} else {
|
|
if (frame.line) {
|
|
if (frame.column) {
|
|
return ` at ${frame.fileName}:${frame.line}:${frame.column}`;
|
|
} else {
|
|
return ` at ${frame.fileName}:${frame.line}`;
|
|
}
|
|
} else {
|
|
return ` at ${frame.fileName}`;
|
|
}
|
|
}
|
|
}
|