• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const {
4  Error,
5} = primordials;
6
7let debug = require('internal/util/debuglog').debuglog('source_map', (fn) => {
8  debug = fn;
9});
10const { findSourceMap } = require('internal/source_map/source_map_cache');
11const {
12  kNoOverride,
13  overrideStackTrace,
14  maybeOverridePrepareStackTrace
15} = require('internal/errors');
16
17// Create a prettified stacktrace, inserting context from source maps
18// if possible.
19const ErrorToString = Error.prototype.toString; // Capture original toString.
20const prepareStackTrace = (globalThis, error, trace) => {
21  // API for node internals to override error stack formatting
22  // without interfering with userland code.
23  // TODO(bcoe): add support for source-maps to repl.
24  if (overrideStackTrace.has(error)) {
25    const f = overrideStackTrace.get(error);
26    overrideStackTrace.delete(error);
27    return f(error, trace);
28  }
29
30  const globalOverride =
31    maybeOverridePrepareStackTrace(globalThis, error, trace);
32  if (globalOverride !== kNoOverride) return globalOverride;
33
34  const errorString = ErrorToString.call(error);
35
36  if (trace.length === 0) {
37    return errorString;
38  }
39  const preparedTrace = trace.map((t, i) => {
40    let str = i !== 0 ? '\n    at ' : '';
41    str = `${str}${t}`;
42    try {
43      const sm = findSourceMap(t.getFileName(), error);
44      if (sm) {
45        // Source Map V3 lines/columns use zero-based offsets whereas, in
46        // stack traces, they start at 1/1.
47        const {
48          originalLine,
49          originalColumn,
50          originalSource
51        } = sm.findEntry(t.getLineNumber() - 1, t.getColumnNumber() - 1);
52        if (originalSource && originalLine !== undefined &&
53            originalColumn !== undefined) {
54          str +=
55`\n        -> ${originalSource.replace('file://', '')}:${originalLine + 1}:${originalColumn + 1}`;
56        }
57      }
58    } catch (err) {
59      debug(err.stack);
60    }
61    return str;
62  });
63  return `${errorString}\n    at ${preparedTrace.join('')}`;
64};
65
66module.exports = {
67  prepareStackTrace,
68};
69