Skip to content

Commit

Permalink
fix(node): Don't overwrite local variables for re-thrown errors (#13644)
Browse files Browse the repository at this point in the history
Another way to fix this issue would be to check via the debugger if the
property exists already on the error object and bail early before we
have local variables. However, this would add an extra round trip call
via the debugger for every error. Since re-thrown errors are far less
likely, I decided instead to just not overwrite existing local
variables.

This PR also adds a `Debugger.resume` call in the catch case to ensure
that they debugger will always resume even if we get errors while
debugging.

It's worth noting that this only fixes the issue in Node v20+ where we
use the async debugging interface.
  • Loading branch information
timfish committed Sep 13, 2024
1 parent df79871 commit bcd2a17
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* eslint-disable no-unused-vars */
const Sentry = require('@sentry/node');
const { loggingTransport } = require('@sentry-internal/node-integration-tests');

Sentry.init({
dsn: 'https://[email protected]/1337',
includeLocalVariables: true,
transport: loggingTransport,
});

class Some {
two(name) {
throw new Error('Enough!');
}
}

function one(name) {
const arr = [1, '2', null];
const obj = {
name,
num: 5,
};
const bool = false;
const num = 0;
const str = '';
const something = undefined;
const somethingElse = null;

const ty = new Some();

ty.two(name);
}

setTimeout(() => {
try {
try {
one('some name');
} catch (e) {
const more = 'here';
throw e;
}
} catch (e) {
Sentry.captureException(e);
}
}, 1000);
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ conditionalTest({ min: 18 })('LocalVariables integration', () => {
});
});

conditionalTest({ min: 20 })('Node v20+', () => {
test('Should retain original local variables when error is re-thrown', done => {
createRunner(__dirname, 'local-variables-rethrow.js')
.expect({ event: EXPECTED_LOCAL_VARIABLES_EVENT })
.start(done);
});
});

test('Includes local variables for caught exceptions when enabled', done => {
createRunner(__dirname, 'local-variables-caught.js').expect({ event: EXPECTED_LOCAL_VARIABLES_EVENT }).start(done);
});
Expand Down
10 changes: 7 additions & 3 deletions packages/node/src/integrations/local-variables/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ async function handlePaused(
// We write the local variables to a property on the error object. These can be read by the integration as the error
// event pass through the SDK event pipeline
await session.post('Runtime.callFunctionOn', {
functionDeclaration: `function() { this.${LOCAL_VARIABLES_KEY} = ${JSON.stringify(frames)}; }`,
functionDeclaration: `function() { this.${LOCAL_VARIABLES_KEY} = this.${LOCAL_VARIABLES_KEY} || ${JSON.stringify(
frames,
)}; }`,
silent: true,
objectId,
});
Expand Down Expand Up @@ -156,8 +158,10 @@ async function startDebugger(): Promise<void> {
}, 1_000);
}
},
_ => {
// ignore any errors
async _ => {
if (isPaused) {
await session.post('Debugger.resume');
}
},
);
});
Expand Down

0 comments on commit bcd2a17

Please sign in to comment.