Skip to content

Commit 88d9268

Browse files
committed
errors: align source-map stacks with spec
Reformat stack traces when --enable-source-maps flag is set to format more likely to fit https://github.com/tc39/proposal-error-stacks PR-URL: #37252 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Ian Sutherland <ian@iansutherland.ca> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Zeyu Yang <himself65@outlook.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
1 parent 2272713 commit 88d9268

8 files changed

+41
-49
lines changed

lib/internal/source_map/prepare_stack_trace.js

+16-9
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ const prepareStackTrace = (globalThis, error, trace) => {
5151
let lastSourceMap;
5252
let lastFileName;
5353
const preparedTrace = ArrayPrototypeJoin(ArrayPrototypeMap(trace, (t, i) => {
54-
let str = i !== 0 ? '\n at ' : '';
55-
str = `${str}${t}`;
54+
const str = i !== 0 ? '\n at ' : '';
5655
try {
5756
// A stack trace will often have several call sites in a row within the
5857
// same file, cache the source map and file content accordingly:
@@ -81,21 +80,29 @@ const prepareStackTrace = (globalThis, error, trace) => {
8180
originalColumn
8281
);
8382
}
84-
// Show both original and transpiled stack trace information:
85-
const prefix = (name && name !== t.getFunctionName()) ?
86-
`\n -> at ${name}` :
87-
'\n ->';
83+
// Construct call site name based on: v8.dev/docs/stack-trace-api:
84+
const fnName = t.getFunctionName() ?? t.getMethodName();
85+
const originalName = `${t.getTypeName() !== 'global' ?
86+
`${t.getTypeName()}.` : ''}${fnName ? fnName : '<anonymous>'}`;
87+
// The original call site may have a different symbol name
88+
// associated with it, use it:
89+
const prefix = (name && name !== originalName) ?
90+
`${name}` :
91+
`${originalName ? originalName : ''}`;
92+
const hasName = !!(name || originalName);
8893
const originalSourceNoScheme =
8994
StringPrototypeStartsWith(originalSource, 'file://') ?
9095
fileURLToPath(originalSource) : originalSource;
91-
str += `${prefix} (${originalSourceNoScheme}:${originalLine + 1}:` +
92-
`${originalColumn + 1})`;
96+
// Replace the transpiled call site with the original:
97+
return `${str}${prefix}${hasName ? ' (' : ''}` +
98+
`${originalSourceNoScheme}:${originalLine + 1}:` +
99+
`${originalColumn + 1}${hasName ? ')' : ''}`;
93100
}
94101
}
95102
} catch (err) {
96103
debug(err.stack);
97104
}
98-
return str;
105+
return `${str}${t}`;
99106
}), '');
100107
return `${errorSource}${errorString}\n at ${preparedTrace}`;
101108
};

test/message/source_map_enclosing_function.out

+5-10
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,11 @@
33
^
44

55
Error: an error!
6-
at functionD (*enclosing-call-site-min.js:1:156)
7-
-> (*enclosing-call-site.js:16:17)
8-
at functionC (*enclosing-call-site-min.js:1:97)
9-
-> (*enclosing-call-site.js:10:3)
10-
at functionB (*enclosing-call-site-min.js:1:60)
11-
-> (*enclosing-call-site.js:6:3)
12-
at functionA (*enclosing-call-site-min.js:1:26)
13-
-> (*enclosing-call-site.js:2:3)
14-
at Object.<anonymous> (*enclosing-call-site-min.js:1:199)
15-
-> (*enclosing-call-site.js:24:3)
6+
at functionD (*enclosing-call-site.js:16:17)
7+
at functionC (*enclosing-call-site.js:10:3)
8+
at functionB (*enclosing-call-site.js:6:3)
9+
at functionA (*enclosing-call-site.js:2:3)
10+
at Object.<anonymous> (*enclosing-call-site.js:24:3)
1611
at Module._compile (node:internal/modules/cjs/loader:*)
1712
at Object.Module._extensions..js (node:internal/modules/cjs/loader:*)
1813
at Module.load (node:internal/modules/cjs/loader:*)

test/message/source_map_reference_error_tabs.out

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
^
44

55
ReferenceError: alert is not defined
6-
at Object.<anonymous> (*tabs.coffee:39:5)
7-
-> *tabs.coffee:26:2*
8-
at Object.<anonymous> (*tabs.coffee:53:4)
9-
-> *tabs.coffee:1:14*
6+
at *tabs.coffee:26:2*
7+
at *tabs.coffee:1:14*
108
at Module._compile (node:internal/modules/cjs/loader:*
119
at Object.Module._extensions..js (node:internal/modules/cjs/loader:*
1210
at Module.load (node:internal/modules/cjs/loader:*

test/message/source_map_throw_catch.out

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@ reachable
33
throw Error('an exception');
44
^
55
Error: an exception
6-
at branch (*typescript-throw.js:20:15)
7-
-> *typescript-throw.ts:18:11*
8-
at Object.<anonymous> (*typescript-throw.js:26:1)
9-
-> *typescript-throw.ts:24:1*
6+
at *typescript-throw.ts:18:11*
7+
at *typescript-throw.ts:24:1*
108
at Module._compile (node:internal/modules/cjs/loader:*)
119
at Object.Module._extensions..js (node:internal/modules/cjs/loader:*)
1210
at Module.load (node:internal/modules/cjs/loader:*)

test/message/source_map_throw_first_tick.out

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@ reachable
33
throw Error('an exception');
44
^
55
Error: an exception
6-
at branch (*typescript-throw.js:20:15)
7-
-> *typescript-throw.ts:18:11*
8-
at Object.<anonymous> (*typescript-throw.js:26:1)
9-
-> *typescript-throw.ts:24:1*
6+
at *typescript-throw.ts:18:11*
7+
at *typescript-throw.ts:24:1*
108
at Module._compile (node:internal/modules/cjs/loader:*)
119
at Object.Module._extensions..js (node:internal/modules/cjs/loader:*)
1210
at Module.load (node:internal/modules/cjs/loader:*)

test/message/source_map_throw_icu.out

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
^
44

55
Error: an error
6-
at Object.createElement (*icu.js:5:7)
7-
-> *icu.jsx:3:23*
8-
at Object.<anonymous> (*icu.js:8:82)
9-
-> *icu.jsx:9:5*
6+
at *icu.jsx:3:23*
7+
at *icu.jsx:9:5*
108
at Module._compile (node:internal/modules/cjs/loader:*
119
at Object.Module._extensions..js (node:internal/modules/cjs/loader:*
1210
at Module.load (node:internal/modules/cjs/loader:*

test/message/source_map_throw_set_immediate.out

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
^
44

55
Error: goodbye
6-
at *uglify-throw.js:1:43
7-
-> at Hello *uglify-throw-original.js:5:9*
8-
at Immediate.<anonymous> (*uglify-throw.js:1:60)
9-
-> *uglify-throw-original.js:9:3*
6+
at Hello *uglify-throw-original.js:5:9*
7+
at *uglify-throw-original.js:9:3*
108
at processImmediate (node:internal/timers:*)

test/parallel/test-source-map-enable.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,11 @@ function nextdir() {
155155
require.resolve('../fixtures/source-map/uglify-throw.js')
156156
]);
157157
assert.strictEqual(
158-
output.stderr.toString().match(/->.*uglify-throw-original\.js:5:9/),
158+
output.stderr.toString().match(/.*uglify-throw-original\.js:5:9/),
159159
null
160160
);
161161
assert.strictEqual(
162-
output.stderr.toString().match(/->.*uglify-throw-original\.js:9:3/),
162+
output.stderr.toString().match(/.*uglify-throw-original\.js:9:3/),
163163
null
164164
);
165165
}
@@ -172,11 +172,11 @@ function nextdir() {
172172
]);
173173
assert.match(
174174
output.stderr.toString(),
175-
/->.*uglify-throw-original\.js:5:9/
175+
/.*uglify-throw-original\.js:5:9/
176176
);
177177
assert.match(
178178
output.stderr.toString(),
179-
/->.*uglify-throw-original\.js:9:3/
179+
/.*uglify-throw-original\.js:9:3/
180180
);
181181
assert.match(output.stderr.toString(), /at Hello/);
182182
}
@@ -187,8 +187,8 @@ function nextdir() {
187187
'--enable-source-maps',
188188
require.resolve('../fixtures/source-map/typescript-throw.js')
189189
]);
190-
assert.ok(output.stderr.toString().match(/->.*typescript-throw\.ts:18:11/));
191-
assert.ok(output.stderr.toString().match(/->.*typescript-throw\.ts:24:1/));
190+
assert.ok(output.stderr.toString().match(/.*typescript-throw\.ts:18:11/));
191+
assert.ok(output.stderr.toString().match(/.*typescript-throw\.ts:24:1/));
192192
}
193193

194194
// Applies source-maps generated by babel to stack trace.
@@ -198,7 +198,7 @@ function nextdir() {
198198
require.resolve('../fixtures/source-map/babel-throw.js')
199199
]);
200200
assert.ok(
201-
output.stderr.toString().match(/->.*babel-throw-original\.js:18:31/)
201+
output.stderr.toString().match(/.*babel-throw-original\.js:18:31/)
202202
);
203203
}
204204

@@ -209,10 +209,10 @@ function nextdir() {
209209
require.resolve('../fixtures/source-map/istanbul-throw.js')
210210
]);
211211
assert.ok(
212-
output.stderr.toString().match(/->.*istanbul-throw-original\.js:5:9/)
212+
output.stderr.toString().match(/.*istanbul-throw-original\.js:5:9/)
213213
);
214214
assert.ok(
215-
output.stderr.toString().match(/->.*istanbul-throw-original\.js:9:3/)
215+
output.stderr.toString().match(/.*istanbul-throw-original\.js:9:3/)
216216
);
217217
}
218218

@@ -223,7 +223,7 @@ function nextdir() {
223223
require.resolve('../fixtures/source-map/babel-esm.mjs')
224224
]);
225225
assert.ok(
226-
output.stderr.toString().match(/->.*babel-esm-original\.mjs:9:29/)
226+
output.stderr.toString().match(/.*babel-esm-original\.mjs:9:29/)
227227
);
228228
}
229229

0 commit comments

Comments
 (0)