Skip to content

Commit ce6b558

Browse files
timfishc298lee
authored andcommitted
fix(node): Local variables skipped after Promise (#11234)
The debugger call stack does not include the `new Promise` frames that are parsed from `error.stack`. This means that when we go through the frames to apply the local variables, the frames don't match up and we bail. This patch ignores those frames when matching functions in the frames.
1 parent 85ec33e commit ce6b558

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

dev-packages/node-integration-tests/suites/public-api/LocalVariables/local-variables-caught.mjs

+8-6
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ Sentry.init({
99
});
1010

1111
class Some {
12-
two(name) {
13-
throw new Error('Enough!');
12+
async two(name) {
13+
return new Promise((_, reject) => {
14+
reject(new Error('Enough!'));
15+
});
1416
}
1517
}
1618

17-
function one(name) {
19+
async function one(name) {
1820
const arr = [1, '2', null];
1921
const obj = {
2022
name,
@@ -30,12 +32,12 @@ function one(name) {
3032

3133
const ty = new Some();
3234

33-
ty.two(name);
35+
await ty.two(name);
3436
}
3537

36-
setTimeout(() => {
38+
setTimeout(async () => {
3739
try {
38-
one('some name');
40+
await one('some name');
3941
} catch (e) {
4042
Sentry.captureException(e);
4143
}

packages/node-experimental/src/integrations/local-variables/local-variables-sync.ts

+9-7
Original file line numberDiff line numberDiff line change
@@ -288,29 +288,31 @@ const _localVariablesSyncIntegration = ((
288288
return;
289289
}
290290

291-
const frameCount = exception.stacktrace?.frames?.length || 0;
291+
// Filter out frames where the function name is `new Promise` since these are in the error.stack frames
292+
// but do not appear in the debugger call frames
293+
const frames = (exception.stacktrace?.frames || []).filter(frame => frame.function !== 'new Promise');
292294

293-
for (let i = 0; i < frameCount; i++) {
295+
for (let i = 0; i < frames.length; i++) {
294296
// Sentry frames are in reverse order
295-
const frameIndex = frameCount - i - 1;
297+
const frameIndex = frames.length - i - 1;
296298

297299
// Drop out if we run out of frames to match up
298-
if (!exception?.stacktrace?.frames?.[frameIndex] || !cachedFrame[i]) {
300+
if (!frames[frameIndex] || !cachedFrame[i]) {
299301
break;
300302
}
301303

302304
if (
303305
// We need to have vars to add
304306
cachedFrame[i].vars === undefined ||
305307
// We're not interested in frames that are not in_app because the vars are not relevant
306-
exception.stacktrace.frames[frameIndex].in_app === false ||
308+
frames[frameIndex].in_app === false ||
307309
// The function names need to match
308-
!functionNamesMatch(exception.stacktrace.frames[frameIndex].function, cachedFrame[i].function)
310+
!functionNamesMatch(frames[frameIndex].function, cachedFrame[i].function)
309311
) {
310312
continue;
311313
}
312314

313-
exception.stacktrace.frames[frameIndex].vars = cachedFrame[i].vars;
315+
frames[frameIndex].vars = cachedFrame[i].vars;
314316
}
315317
}
316318

0 commit comments

Comments
 (0)