lts/lib/internal/source_map/prepare_stack_trace.js
'use strict';
const {
Error,
} = primordials;
const debug = require('internal/util/debuglog').debuglog('source_map');
const { findSourceMap } = require('internal/source_map/source_map_cache');
const {
kNoOverride,
overrideStackTrace,
maybeOverridePrepareStackTrace
} = require('internal/errors');
// Create a prettified stacktrace, inserting context from source maps
// if possible.
const ErrorToString = Error.prototype.toString; // Capture original toString.
const prepareStackTrace = (globalThis, error, trace) => {
// API for node internals to override error stack formatting
// without interfering with userland code.
// TODO(bcoe): add support for source-maps to repl.
if (overrideStackTrace.has(error)) {
const f = overrideStackTrace.get(error);
overrideStackTrace.delete(error);
return f(error, trace);
}
const globalOverride =
maybeOverridePrepareStackTrace(globalThis, error, trace);
if (globalOverride !== kNoOverride) return globalOverride;
const errorString = ErrorToString.call(error);
if (trace.length === 0) {
return errorString;
}
const preparedTrace = trace.map((t, i) => {
let str = i !== 0 ? '\n at ' : '';
str = `${str}${t}`;
try {
const sm = findSourceMap(t.getFileName(), error);
if (sm) {
// Source Map V3 lines/columns use zero-based offsets whereas, in
// stack traces, they start at 1/1.
const {
originalLine,
originalColumn,
originalSource
} = sm.findEntry(t.getLineNumber() - 1, t.getColumnNumber() - 1);
if (originalSource && originalLine !== undefined &&
originalColumn !== undefined) {
str +=
`\n -> ${originalSource.replace('file://', '')}:${originalLine + 1}:${originalColumn + 1}`;
}
}
} catch (err) {
debug(err.stack);
}
return str;
});
return `${errorString}\n at ${preparedTrace.join('')}`;
};
module.exports = {
prepareStackTrace,
};