summaryrefslogtreecommitdiff
path: root/lib/internal/util/inspect.js
diff options
context:
space:
mode:
authorRuben Bridgewater <ruben@bridgewater.de>2019-04-02 07:56:14 +0200
committerRuben Bridgewater <ruben@bridgewater.de>2019-04-15 17:30:50 +0200
commit1940114ac323695c758f21a00394b958a68d8428 (patch)
treeac64cc180479672da3eb6dfee02642fde784cbd0 /lib/internal/util/inspect.js
parent693401d0ddd752e5fa47b882e56e252c42c94c0e (diff)
downloadandroid-node-v8-1940114ac323695c758f21a00394b958a68d8428.tar.gz
android-node-v8-1940114ac323695c758f21a00394b958a68d8428.tar.bz2
android-node-v8-1940114ac323695c758f21a00394b958a68d8428.zip
util: highlight stack frames
Using `util.inspect` on errors is going to highlight userland and node_module stack frames from now on. This is done by marking Node.js core frames grey and frames that contain `node_modules` in their path yellow. That way it's easy to grasp what frames belong to what code. PR-URL: https://github.com/nodejs/node/pull/27052 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'lib/internal/util/inspect.js')
-rw-r--r--lib/internal/util/inspect.js37
1 files changed, 35 insertions, 2 deletions
diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js
index a31ee5b8eb..08f627db88 100644
--- a/lib/internal/util/inspect.js
+++ b/lib/internal/util/inspect.js
@@ -86,6 +86,8 @@ const {
const assert = require('internal/assert');
+const { NativeModule } = require('internal/bootstrap/loaders');
+
let hexSlice;
const inspectDefaultOptions = Object.seal({
@@ -115,6 +117,9 @@ const strEscapeSequencesReplacerSingle = /[\x00-\x1f\x5c]/g;
const keyStrRegExp = /^[a-zA-Z_][a-zA-Z_0-9]*$/;
const numberRegExp = /^(0|[1-9][0-9]*)$/;
+const coreModuleRegExp = /^ at (?:[^/\\(]+ \(|)((?<![/\\]).+)\.js:\d+:\d+\)?$/;
+const nodeModulesRegExp = /[/\\]node_modules[/\\](.+?)(?=[/\\])/g;
+
const readableRegExps = {};
const kMinLineLength = 16;
@@ -253,7 +258,8 @@ inspect.styles = Object.assign(Object.create(null), {
symbol: 'green',
date: 'magenta',
// "name": intentionally not styling
- regexp: 'red'
+ regexp: 'red',
+ module: 'underline'
});
function addQuotes(str, quotes) {
@@ -838,10 +844,37 @@ function formatError(err, constructor, tag, ctx) {
}
}
}
+ // Ignore the error message if it's contained in the stack.
+ let pos = err.message && stack.indexOf(err.message) || -1;
+ if (pos !== -1)
+ pos += err.message.length;
// Wrap the error in brackets in case it has no stack trace.
- const stackStart = stack.indexOf('\n at');
+ const stackStart = stack.indexOf('\n at', pos);
if (stackStart === -1) {
stack = `[${stack}]`;
+ } else if (ctx.colors) {
+ // Highlight userland code and node modules.
+ let newStack = stack.slice(0, stackStart);
+ const lines = stack.slice(stackStart + 1).split('\n');
+ for (const line of lines) {
+ const core = line.match(coreModuleRegExp);
+ if (core !== null && NativeModule.exists(core[1])) {
+ newStack += `\n${ctx.stylize(line, 'undefined')}`;
+ } else {
+ // This adds underscores to all node_modules to quickly identify them.
+ let nodeModule;
+ newStack += '\n';
+ let pos = 0;
+ while (nodeModule = nodeModulesRegExp.exec(line)) {
+ // '/node_modules/'.length === 14
+ newStack += line.slice(pos, nodeModule.index + 14);
+ newStack += ctx.stylize(nodeModule[1], 'module');
+ pos = nodeModule.index + nodeModule[0].length;
+ }
+ newStack += pos === 0 ? line : line.slice(pos);
+ }
+ }
+ stack = newStack;
}
// The message and the stack have to be indented as well!
if (ctx.indentationLvl !== 0) {