Skip to content

test(node): Add test demonstrating withIsolationScope data loss on uncaught errors #16479

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ app.get('/test/isolationScope', () => {
throw new Error('isolation_test_error');
});

app.get('/test/withIsolationScope', () => {
Sentry.withIsolationScope(iScope => {
iScope.setTag('with-isolation-scope', 'tag');
throw new Error('with_isolation_scope_test_error');
});
});

Sentry.setupExpressErrorHandler(app);

startExpressServerAndSendPortToRunner(app);
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,49 @@ test('isolation scope is applied to thrown error caught by global handler', asyn
runner.makeRequest('get', '/test/isolationScope', { expectError: true });
await runner.completed();
});

/**
* This test shows that an inner isolation scope, created via `withIsolationScope`, is not applied to the error.
*
* This behaviour occurs because, just like in the test above where we use `getIsolationScope().setTag`,
* this isolation scope again is only valid as long as we're in the callback.
*
* So why _does_ the http isolation scope get applied then? Because express' error handler applies on
* a per-request basis, meaning, it's called while we're inside the isolation scope of the http request,
* created from our `httpIntegration`.
*/
test('withIsolationScope scope is NOT applied to thrown error caught by global handler', async () => {
const runner = createRunner(__dirname, 'server.ts')
.expect({
event: {
exception: {
values: [
{
mechanism: {
type: 'middleware',
handled: false,
},
type: 'Error',
value: 'with_isolation_scope_test_error',
stacktrace: {
frames: expect.arrayContaining([
expect.objectContaining({
function: expect.any(String),
lineno: expect.any(Number),
colno: expect.any(Number),
}),
]),
},
},
],
},
// 'with-isolation-scope' tag is not applied to the event
tags: expect.not.objectContaining({ 'with-isolation-scope': expect.anything() }),
},
})
.start();

runner.makeRequest('get', '/test/withIsolationScope', { expectError: true });

await runner.completed();
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ app.get('/test/isolationScope', () => {
throw new Error('isolation_test_error');
});

app.get('/test/withIsolationScope', () => {
Sentry.withIsolationScope(iScope => {
iScope.setTag('with-isolation-scope', 'tag');
throw new Error('with_isolation_scope_test_error');
});
});

Sentry.setupExpressErrorHandler(app);

startExpressServerAndSendPortToRunner(app);
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ test('withScope scope is NOT applied to thrown error caught by global handler',
/**
* This test shows that the isolation scope set tags are applied correctly to the error.
*/
test('isolation scope is applied to thrown error caught by global handler', async () => {
test('http requestisolation scope is applied to thrown error caught by global handler', async () => {
const runner = createRunner(__dirname, 'server.ts')
.expect({
event: {
Expand Down Expand Up @@ -90,3 +90,49 @@ test('isolation scope is applied to thrown error caught by global handler', asyn

await runner.completed();
});

/**
* This test shows that an inner isolation scope, created via `withIsolationScope`, is not applied to the error.
*
* This behaviour occurs because, just like in the test above where we use `getIsolationScope().setTag`,
* this isolation scope again is only valid as long as we're in the callback.
*
* So why _does_ the http isolation scope get applied then? Because express' error handler applies on
* a per-request basis, meaning, it's called while we're inside the isolation scope of the http request,
* created from our `httpIntegration`.
*/
test('withIsolationScope scope is NOT applied to thrown error caught by global handler', async () => {
const runner = createRunner(__dirname, 'server.ts')
.expect({
event: {
exception: {
values: [
{
mechanism: {
type: 'middleware',
handled: false,
},
type: 'Error',
value: 'with_isolation_scope_test_error',
stacktrace: {
frames: expect.arrayContaining([
expect.objectContaining({
function: expect.any(String),
lineno: expect.any(Number),
colno: expect.any(Number),
}),
]),
},
},
],
},
// 'with-isolation-scope' tag is not applied to the event
tags: expect.not.objectContaining({ 'with-isolation-scope': expect.anything() }),
},
})
.start();

runner.makeRequest('get', '/test/withIsolationScope', { expectError: true });

await runner.completed();
});
Loading