Compare commits

...

3 Commits

@ -1,6 +1,6 @@
{ {
"name": "error-chain", "name": "error-chain",
"version": "0.1.1", "version": "0.1.2",
"main": "index.js", "main": "index.js",
"repository": "git@git.cryto.net:joepie91/node-error-chain.git", "repository": "git@git.cryto.net:joepie91/node-error-chain.git",
"author": "Sven Slootweg <admin@cryto.net>", "author": "Sven Slootweg <admin@cryto.net>",

@ -1,6 +1,7 @@
"use strict"; "use strict";
const chalk = require("chalk"); const chalk = require("chalk");
const syncpipe = require("syncpipe");
const { validateArguments } = require("@validatem/core"); const { validateArguments } = require("@validatem/core");
const required = require("@validatem/required"); const required = require("@validatem/required");
@ -12,14 +13,50 @@ const stripErrorFromStack = require("./strip-error-from-stack");
const isInstanceOf = require("./is-instance-of"); const isInstanceOf = require("./is-instance-of");
const getChain = require("../get-chain"); const getChain = require("../get-chain");
function formattedErrorHeading(error, colorAll = false) { function prefixExtraLines(string, prefix) {
let formattedMessage = error.message.trim().replace(/\n/g, " \\n "); return string
.split("\n")
.map((line, i) => {
if (i > 0) {
return prefix + line;
} else {
return line;
}
})
.join("\n");
}
function formattedErrorHeading(error, colorAll = false, indentation) {
let formattedMessage = syncpipe(error.message, [
(_) => _.trim(),
(_) => (indentation != null)
? prefixExtraLines(_, indentation)
: _
]);
let formattedName = chalk.red(`${chalk.bold(error.name)}:`); let formattedName = chalk.red(`${chalk.bold(error.name)}:`);
let coloredMessage = (colorAll === true) ? chalk.red(formattedMessage) : formattedMessage; let coloredMessage = (colorAll === true) ? chalk.red(formattedMessage) : formattedMessage;
return `${formattedName} ${coloredMessage}`; return `${formattedName} ${coloredMessage}`;
// return chalk.red(`${chalk.bold(error.name)}: ${formattedMessage}`); }
function formattedError(error, indentation = "", prefix = "") {
let strippedStack = stripErrorFromStack(error.stack);
let formattedStack = strippedStack.split("\n").map((line) => {
if (line.trim().length === 0) {
return null;
} else if (line[0] === " ") {
return indentation + line;
} else {
return indentation + ` ${line}`;
}
}).filter(line => line != null).join("\n");
let heading = indentation + prefix + formattedErrorHeading(error);
return `${heading}\n${formattedStack}`;
} }
module.exports = function renderError(_error, _options) { module.exports = function renderError(_error, _options) {
@ -34,49 +71,41 @@ module.exports = function renderError(_error, _options) {
let {allStacktraces} = options; let {allStacktraces} = options;
let errors = getChain(error); let errors = getChain(error);
let detailedErrorsToDisplay = (allStacktraces === true) ? errors : errors.slice(-1);
let summary = errors.map((error, i) => {
let prefix = (i > 0) ? "⤷ " : "";
/* IDEA: After every summarized error, add a summarized stacktrace; that is, a stacktrace that only contains the 'user code' entries that might point the developer at the source of the problem. To do that, we should filter out all node_modules and error-chain stuff, as well as internals like timers.js. Then, we should deduplicate lines across stacktraces, and hide the function name if it's boilerplate (eg. Promise.try.then stuff). Try this out with the 'rpm' regex in the CVM smartctl wrapper, as that covers all bases; duplication, stacktraces without user code, etc. */ if (errors.length === 1) {
// let cleanStack = error.stack.split("\n").filter((line) => { // Special case: there's not actually a cause chain, so we should render the error more simply
// return (!line.includes("node_modules") return formattedError(errors[0]);
// && !line.includes("node-error-chain") } else {
// && !line.includes("(timers.js") let detailedErrorsToDisplay = (allStacktraces === true) ? errors : errors.slice(-1);
// && !line.includes("<anonymous>")
// );
// }).join("\n");
// console.log(cleanStack); let summary = errors.map((error, i) => {
let prefix = (i > 0) ? "⤷ " : "";
return prefix + formattedErrorHeading(error); /* IDEA: After every summarized error, add a summarized stacktrace; that is, a stacktrace that only contains the 'user code' entries that might point the developer at the source of the problem. To do that, we should filter out all node_modules and error-chain stuff, as well as internals like timers.js. Then, we should deduplicate lines across stacktraces, and hide the function name if it's boilerplate (eg. Promise.try.then stuff). Try this out with the 'rpm' regex in the CVM smartctl wrapper, as that covers all bases; duplication, stacktraces without user code, etc. */
}).join("\n"); // let cleanStack = error.stack.split("\n").filter((line) => {
// return (!line.includes("node_modules")
// && !line.includes("node-error-chain")
// && !line.includes("(timers.js")
// && !line.includes("<anonymous>")
// );
// }).join("\n");
let stacktraces = detailedErrorsToDisplay.map((error, i) => { // console.log(cleanStack);
let causedByPrefix = (i > 0 ? "Caused by: " : "");
let causedByPadding = (i > 0) ? " " : "";
let strippedStack = stripErrorFromStack(error.stack); return prefix + formattedErrorHeading(error, false, " ");
}).join("\n");
let formattedStack = strippedStack.split("\n").map((line) => {
if (line.trim().length === 0) {
return null;
} else if (line[0] === " ") {
return causedByPadding + line;
} else {
return causedByPadding + ` ${line}`;
}
}).filter(line => line != null).join("\n");
let heading = causedByPadding + causedByPrefix + formattedErrorHeading(error); let stacktraces = detailedErrorsToDisplay.map((error, i) => {
let causedByPrefix = (i > 0 ? "Caused by: " : "");
let causedByPadding = (i > 0) ? " " : "";
return `${heading}\n${formattedStack}`; return formattedError(error, causedByPadding, causedByPrefix);
}).join("\n\n"); }).join("\n\n");
let stacktraceSection = (allStacktraces === true) let stacktraceSection = (allStacktraces === true)
? `${chalk.cyan("All stacktraces:")}\n\n${stacktraces}` ? `${chalk.cyan("All stacktraces:")}\n\n${stacktraces}`
: `${chalk.cyan("Stacktrace for original error:")}\n\n${stacktraces}`; : `${chalk.cyan("Stacktrace for original error:")}\n\n${stacktraces}`;
return `${summary}\n\n${stacktraceSection}`; return `${summary}\n\n${stacktraceSection}`;
}
}; };

Loading…
Cancel
Save