Skip to content

Commit 507688e

Browse files
util: add sourcemap support to getCallSite
1 parent 44fe937 commit 507688e

File tree

5 files changed

+100
-3
lines changed

5 files changed

+100
-3
lines changed

doc/api/util.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ util.formatWithOptions({ colors: true }, 'See object %O', { foo: 42 });
364364
// when printed to a terminal.
365365
```
366366

367-
## `util.getCallSite(frames)`
367+
## `util.getCallSite(frames, options)`
368368

369369
> Stability: 1.1 - Active development
370370
@@ -374,6 +374,9 @@ added: v22.9.0
374374

375375
* `frames` {number} Number of frames returned in the stacktrace.
376376
**Default:** `10`. Allowable range is between 1 and 200.
377+
* `options` {Object}
378+
* `sourceMap` {boolean} Reconstruct the original location in the stacktrace from the source-map.
379+
Enabled by default with the flag `--enable-source-maps`.
377380
* Returns: {Object\[]} An array of stacktrace objects
378381
* `functionName` {string} Returns the name of the function associated with this stack frame.
379382
* `scriptName` {string} Returns the name of the resource that contains the script for the

lib/util.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const {
6161
validateNumber,
6262
validateString,
6363
validateOneOf,
64+
validateObject,
6465
} = require('internal/validators');
6566
const {
6667
isReadableStream,
@@ -74,6 +75,7 @@ function lazyUtilColors() {
7475
utilColors ??= require('internal/util/colors');
7576
return utilColors;
7677
}
78+
const { getOptionValue } = require('internal/options');
7779

7880
const binding = internalBinding('util');
7981

@@ -333,9 +335,23 @@ function parseEnv(content) {
333335
* @param {number} frames
334336
* @returns {object}
335337
*/
336-
function getCallSite(frames = 10) {
338+
function getCallSite(frames = 10, options) {
339+
if (options === undefined) {
340+
if (typeof frames === 'object') {
341+
options = frames;
342+
frames = 10;
343+
} else {
344+
options = {};
345+
};
346+
}
337347
// Using kDefaultMaxCallStackSizeToCapture as reference
338348
validateNumber(frames, 'frames', 1, 200);
349+
validateObject(options, 'options');
350+
// If options.sourceMaps is true or if sourceMaps are enabled but the option.sourceMaps is not set explictly to false
351+
if (options.sourceMap === true || (getOptionValue('--enable-source-maps') && options.sourceMap !== false)) {
352+
const { mapCallSite } = require('internal/source_map/source_map_cache');
353+
return mapCallSite(binding.getCallSite(frames));
354+
}
339355
return binding.getCallSite(frames);
340356
};
341357

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const { getCallSite } = require('node:util');
2+
3+
interface CallSite {
4+
A;
5+
B;
6+
}
7+
8+
const callSite = getCallSite({ sourceMap: false })[0];
9+
10+
console.log('mapCallSite: ', callSite);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const { getCallSite } = require('node:util');
2+
3+
interface CallSite {
4+
A;
5+
B;
6+
}
7+
8+
const callSite = getCallSite()[0];
9+
10+
console.log('getCallSite: ', callSite);

test/parallel/test-util-getCallSite.js

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,17 @@ const assert = require('node:assert');
5353
code: 'ERR_OUT_OF_RANGE'
5454
}));
5555
assert.throws(() => {
56-
getCallSite({});
56+
getCallSite([]);
57+
}, common.expectsError({
58+
code: 'ERR_INVALID_ARG_TYPE'
59+
}));
60+
assert.throws(() => {
61+
getCallSite({}, {});
62+
}, common.expectsError({
63+
code: 'ERR_INVALID_ARG_TYPE'
64+
}));
65+
assert.throws(() => {
66+
getCallSite(10, 10);
5767
}, common.expectsError({
5868
code: 'ERR_INVALID_ARG_TYPE'
5969
}));
@@ -104,3 +114,51 @@ const assert = require('node:assert');
104114
assert.notStrictEqual(callsite.length, 0);
105115
Error.stackTraceLimit = originalStackTraceLimit;
106116
}
117+
118+
{
119+
const { status, stderr, stdout } = spawnSync(process.execPath, [
120+
'--no-warnings',
121+
'--experimental-transform-types',
122+
fixtures.path('typescript/ts/test-get-callsite.ts'),
123+
]);
124+
125+
const output = stdout.toString();
126+
assert.strictEqual(stderr.toString(), '');
127+
assert.match(output, /lineNumber: 8/);
128+
assert.match(output, /column: 18/);
129+
assert.match(output, /typescript\/ts\/test-get-callsite\.ts/);
130+
assert.strictEqual(status, 0);
131+
}
132+
133+
{
134+
const { status, stderr, stdout } = spawnSync(process.execPath, [
135+
'--no-warnings',
136+
'--experimental-transform-types',
137+
'--no-enable-source-maps',
138+
fixtures.path('typescript/ts/test-get-callsite.ts'),
139+
]);
140+
141+
const output = stdout.toString();
142+
assert.strictEqual(stderr.toString(), '');
143+
// Line should be wrong when sourcemaps are disable
144+
assert.match(output, /lineNumber: 2/);
145+
assert.match(output, /column: 18/);
146+
assert.match(output, /typescript\/ts\/test-get-callsite\.ts/);
147+
assert.strictEqual(status, 0);
148+
}
149+
150+
{
151+
// Source maps should be disabled when options.sourceMap is false
152+
const { status, stderr, stdout } = spawnSync(process.execPath, [
153+
'--no-warnings',
154+
'--experimental-transform-types',
155+
fixtures.path('typescript/ts/test-get-callsite-explicit.ts'),
156+
]);
157+
158+
const output = stdout.toString();
159+
assert.strictEqual(stderr.toString(), '');
160+
assert.match(output, /lineNumber: 2/);
161+
assert.match(output, /column: 18/);
162+
assert.match(output, /typescript\/ts\/test-get-callsite-explicit\.ts/);
163+
assert.strictEqual(status, 0);
164+
}

0 commit comments

Comments
 (0)