UNPKG

pig-dam-core

Version:

Library that should be included in every Pig DAM project we build

134 lines (133 loc) 4.66 kB
"use strict"; /** * Date: 3/5/2018 * Time: 9:10 PM * @license MIT (see project's LICENSE file) * * NOTE: we do not want to use PigError here 'cause he uses us */ Object.defineProperty(exports, "__esModule", { value: true }); exports.parseStackLine = exports.parseStack = exports.groomStack = exports.getStack = void 0; const _ = require("lodash"); /** * Gets the current execution stack as a string. * Note: it strips the message off of the stack */ function getStack({ popCount = 0, maxLines = 10 } = {}) { return groomStack(new Error(), { maxLines, // pop ourselves popCount: popCount + 1 }); } exports.getStack = getStack; /** * Gets the stack, parses it via `parseStack` and refines it as requested * @param errorOrStack - either is the stack or is an error from which we will pull the stack * @param popCount - number of lines to pop off the top * @param maxLines - max number of stack lines to include (stacks can get very long and noisy * And returns him back to you so you can hug and kiss him and call him? */ function groomStack(errorOrStack, { popCount = 0, maxLines = 10 } = {}) { const { lines } = parseStack(errorOrStack); if (popCount > 0) { lines.splice(0, popCount); } if (maxLines < lines.length) { lines.splice(maxLines); } return lines.join("\n"); } exports.groomStack = groomStack; /** * Splits this fellow up into the message and the call history. It removes all formatting (leading * and trailing white space). * * Sample stack * "Error Message\n" + * " at repl:1:7\n" + * " at Script.runInThisContext (vm.js:120:20)\n" + * " at REPLServer.defaultEval (repl.js:431:29)\n" + * " ..."; */ function parseStack(errorOrStack) { // it appears that not all errors create themselves as instances of Error... const stack = (typeof errorOrStack === "string") ? errorOrStack : errorOrStack.stack; // the reason we don't remove all whitespace around the newline is so that we can retain // message formatting. For example, it may be stringified JSON. We want to keep that whitespace. const split = stack.split(/\n/) .filter(line => line.trim() !== ""); // to find the first line in the execution history of the stack we are going to use our // `parseStackLine` and wait for it to succeed and we will assume that is the first line // in the stacks execution history const firstExecutionLine = _.findIndex(split, line => { try { parseStackLine(line); return true; } catch (error) { return false; } }); return { lines: split .slice(firstExecutionLine) .map(_.trim), message: split .slice(0, firstExecutionLine) .join("\n") }; } exports.parseStack = parseStack; /** * Parses a line of call history in a stack (not the message). * @throws {Error} if unable to parse */ function parseStackLine(line) { let match; /** * As documented by nodejs (https://nodejs.org/api/errors.html#errors_error_stack) * the following variations exist: * at speedy (/home/gbusey/file.js:6:11) * at makeFaster (/home/gbusey/file.js:5:3) * at Object.<anonymous> (/home/gbusey/file.js:10:1) * at Module._compile (module.js:456:26) * at Object.Module._extensions..js (module.js:474:10) * at Module.load (module.js:356:32) * at Function.Module._load (module.js:312:12) * at Function.Module.runMain (module.js:497:10) * at startup (node.js:119:16) * at node.js:906:3 */ const regexWithMethod = /^\s*at\s*(([^\s.]+)(\.(\S+))?)\s*\((.+):(\d+):(\d+)\)\s*$/; const regexWithoutMethod = /^\s*at\s*(.+):(\d+):(\d+)\s*$/; match = line.match(regexWithMethod); if (match) { // @ts-ignore return _.omitBy({ column: Number(match[7]), // if we could not isolate a method then there is no context context: (match[4]) ? match[2] : undefined, line: Number(match[6]), // if there is no context then we take thw whole thing method: (match[4]) ? match[4] : match[1], module: match[5] }, _.isUndefined); } match = line.match(regexWithoutMethod); if (match) { return { column: Number(match[3]), line: Number(match[2]), module: match[1] }; } throw new Error(`unable to parse "${line}"`); } exports.parseStackLine = parseStackLine;