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