Skip to content

Commit 8d9f30a

Browse files
committed
fixup! lib: add util.getCallSite() API
1 parent 7d1b8ea commit 8d9f30a

File tree

3 files changed

+59
-4
lines changed

3 files changed

+59
-4
lines changed

lib/util.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,10 @@ function parseEnv(content) {
279279
* Returns the callSite
280280
* @returns {object}
281281
*/
282-
function getCallSite() {
283-
return binding.getCallSite();
282+
function getCallSite(frames = 10) {
283+
// Using kDefaultMaxCallStackSizeToCapture as reference
284+
validateNumber(frames, 'frames', 1, 200);
285+
return binding.getCallSite(frames);
284286
};
285287

286288
// Keep the `exports =` so that various functions can still be monkeypatched

src/node_util.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,13 @@ static void GetCallSite(const FunctionCallbackInfo<Value>& args) {
258258
Environment* env = Environment::GetCurrent(args);
259259
Isolate* isolate = env->isolate();
260260

261+
CHECK_EQ(args.Length(), 1);
262+
CHECK(args[0]->IsNumber());
263+
const uint32_t frames = args[0].As<Uint32>()->Value();
264+
265+
// +1 for disregarding node:util
261266
Local<StackTrace> stack =
262-
StackTrace::CurrentStackTrace(isolate, env->stack_trace_limit());
267+
StackTrace::CurrentStackTrace(isolate, frames + 1);
263268
Local<Array> callsites = Array::New(isolate);
264269

265270
// Frame 0 is node:util. It should be skipped.

test/parallel/test-util-getCallSite.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
require('../common');
3+
const common = require('../common');
44

55
const fixtures = require('../common/fixtures');
66
const file = fixtures.path('get-call-site.js');
@@ -19,6 +19,54 @@ const assert = require('node:assert');
1919
);
2020
}
2121

22+
{
23+
const callsite = getCallSite(3);
24+
assert.strictEqual(callsite.length, 3);
25+
assert.match(
26+
callsite[0].scriptName,
27+
/test-util-getCallSite/,
28+
'node:util should be ignored',
29+
);
30+
}
31+
32+
{
33+
const callsite = getCallSite(3.6);
34+
assert.strictEqual(callsite.length, 3);
35+
}
36+
37+
{
38+
const callsite = getCallSite(3.4);
39+
assert.strictEqual(callsite.length, 3);
40+
}
41+
42+
{
43+
assert.throws(() => {
44+
// Max than kDefaultMaxCallStackSizeToCapture
45+
getCallSite(201);
46+
}, common.expectsError({
47+
code: 'ERR_OUT_OF_RANGE'
48+
}));
49+
assert.throws(() => {
50+
getCallSite(-1);
51+
}, common.expectsError({
52+
code: 'ERR_OUT_OF_RANGE'
53+
}));
54+
assert.throws(() => {
55+
getCallSite({});
56+
}, common.expectsError({
57+
code: 'ERR_INVALID_ARG_TYPE'
58+
}));
59+
}
60+
61+
{
62+
const callsite = getCallSite(1);
63+
assert.strictEqual(callsite.length, 1);
64+
assert.match(
65+
callsite[0].scriptName,
66+
/test-util-getCallSite/,
67+
'node:util should be ignored',
68+
);
69+
}
2270

2371
{
2472
const { status, stderr, stdout } = spawnSync(

0 commit comments

Comments
 (0)