downtimer
Version:
Timeouts, but a little more relaxing
121 lines • 4.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseStackFromError = parseStackFromError;
exports.getStackTrace = getStackTrace;
exports.displayTrace = displayTrace;
exports.displayError = displayError;
/** Source row, only if trailing ')' has been trimmed */
const SOURCE_ROW_REGEX = /:\d+:\d+$/;
/** Source column, only if trailing ')' has been trimmed */
const SOURCE_COL_REGEX = /:\d+$/;
const AT_REGEX = /^at /;
/** Find opening '(', which denotes start of filename */
const FILENAME_START_REGEX = /\(/;
/** Find closing ')', which denotes end of filename */
const FILENAME_END_REGEX = /\)$/;
/** Match the filename, source position and surrounding parentheses */
const FILENAME_REGEX = /\(.+:\d+:\d+\)$/;
/** Determine the function name, given a line in a stack trace */
function determineFunctionName(line) {
const open = FILENAME_START_REGEX.exec(line);
if (open === null) {
return null;
}
// Remove leading 'at '
return line.slice(0, open.index - 1).replace(AT_REGEX, '');
}
/** Determine the file name, given a line in a stack trace */
function determineFileName(line) {
// Search for text between first '(' and last ':line:column)'
const match = FILENAME_REGEX.exec(line);
if (match) {
// Slice out the parentheses
return match[0].replace(FILENAME_END_REGEX, '').replace(SOURCE_ROW_REGEX, '').slice(1);
}
else {
// Trace had no function, just remove the 'at' and the and file position
return line.replace(AT_REGEX, '').replace(SOURCE_ROW_REGEX, '');
}
}
/** Determine source position, given a line in a stack trace */
function determineSourcePosition(line) {
line = line.replace(FILENAME_END_REGEX, '');
const rowIdx = line.search(SOURCE_ROW_REGEX);
const colIdx = line.search(SOURCE_COL_REGEX);
if (rowIdx === -1) {
return null;
}
const row = parseInt(line.slice(rowIdx + 1, colIdx));
const col = parseInt(line.slice(colIdx + 1));
return [row, col];
}
/** Given a line in a stack trace, produce a `StackFrame` object */
function parseStackFrame(line) {
line = line.trim();
return {
file: determineFileName(line),
function: determineFunctionName(line),
pos: determineSourcePosition(line),
};
}
/** Parse a stack trace from an Error object */
function parseStackFromError(e) {
// Remove first line with error contents
return e.stack.split('\n').slice(1).map(parseStackFrame);
}
/** Get the current stack trace */
function getStackTrace() {
return parseStackFromError(new Error());
}
/**
* Return whether a file is relevant to the current project
*
* True if all of:
* * File is within the current working directory
* * File is not in `node_modules`
*/
function pathIsRelevant(file) {
const cwd = `${process.cwd()}/`;
const nodeModules = `${process.cwd()}/node_modules`;
return file.startsWith(cwd) && !file.startsWith(nodeModules);
}
/** Add colors to file path, greying out sections outside of the working directory */
function colorizePath(file, colors) {
const cwd = `${process.cwd()}/`;
if (pathIsRelevant(file)) {
return `${colors.quiet(cwd)}${colors.file(file.replace(cwd, ''))}`;
}
else {
return colors.quiet(file);
}
}
/** Given a stack trace, display it to the user in a colorful and friendly manner */
function displayTrace(trace, colors) {
var _a;
for (const frame of trace) {
const fn = colors.func((_a = frame.function) !== null && _a !== void 0 ? _a : '<unknown>');
const fileIsRelevant = pathIsRelevant(frame.file);
const file = colorizePath(frame.file, colors);
let pos = '';
if (frame.pos) {
pos = `:${frame.pos[0]}:${frame.pos[1]}`;
if (!fileIsRelevant) {
pos = colors.quiet(pos);
}
}
console.log(` at ${fn} (${file}${pos})`);
}
}
/** Given an Error object, display it to the user in a colorful and friendly manner */
function displayError(e, colors) {
if (e instanceof Error) {
const stack = parseStackFromError(e);
console.log(` ${colors.error(e.name)}: ${e.message}`);
displayTrace(stack, colors);
}
else {
console.log(colors.error(' Error object is not of type `Error`. Cannot determine stack trace.'));
console.log(colors.error(String(e)));
}
}
//# sourceMappingURL=stackTrace.js.map