Skip to content

Commit 496d98c

Browse files
authored
feat(nextjs): Fork isolation scope for root spans on Next.js edge runtime (#13919)
We need to hoist the isolation scope forking logic out of the build-time instrumentation.
1 parent 1392e1b commit 496d98c

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

packages/nextjs/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"access": "public"
6969
},
7070
"dependencies": {
71+
"@opentelemetry/api": "^1.9.0",
7172
"@opentelemetry/instrumentation-http": "0.53.0",
7273
"@opentelemetry/semantic-conventions": "^1.27.0",
7374
"@rollup/plugin-commonjs": "26.0.1",

packages/nextjs/src/edge/index.ts

+30-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1-
import { applySdkMetadata, registerSpanErrorInstrumentation } from '@sentry/core';
1+
import { context } from '@opentelemetry/api';
2+
import {
3+
applySdkMetadata,
4+
getCapturedScopesOnSpan,
5+
getCurrentScope,
6+
getIsolationScope,
7+
getRootSpan,
8+
registerSpanErrorInstrumentation,
9+
setCapturedScopesOnSpan,
10+
} from '@sentry/core';
11+
212
import { GLOBAL_OBJ } from '@sentry/utils';
313
import type { VercelEdgeOptions } from '@sentry/vercel-edge';
414
import { getDefaultIntegrations, init as vercelEdgeInit } from '@sentry/vercel-edge';
515

16+
import { getScopesFromContext } from '@sentry/opentelemetry';
617
import { isBuild } from '../common/utils/isBuild';
718
import { distDirRewriteFramesIntegration } from './distDirRewriteFramesIntegration';
819

@@ -39,7 +50,24 @@ export function init(options: VercelEdgeOptions = {}): void {
3950

4051
applySdkMetadata(opts, 'nextjs');
4152

42-
vercelEdgeInit(opts);
53+
const client = vercelEdgeInit(opts);
54+
55+
// Create/fork an isolation whenever we create root spans. This is ok because in Next.js we only create root spans on the edge for incoming requests.
56+
client?.on('spanStart', span => {
57+
if (span === getRootSpan(span)) {
58+
const scopes = getCapturedScopesOnSpan(span);
59+
60+
const isolationScope = (scopes.isolationScope || getIsolationScope()).clone();
61+
const scope = scopes.scope || getCurrentScope();
62+
63+
const currentScopesPointer = getScopesFromContext(context.active());
64+
if (currentScopesPointer) {
65+
currentScopesPointer.isolationScope = isolationScope;
66+
}
67+
68+
setCapturedScopesOnSpan(span, scope, isolationScope);
69+
}
70+
});
4371
}
4472

4573
/**

0 commit comments

Comments
 (0)