Skip to content

Commit b0e1db0

Browse files
authored
feat(sveltekit): Switch to Otel-based @sentry/node package (#11075)
This PR switches the underlying Node SDK from `@sentry/node-experimental` (aka the "legacy" v7 Node SDK) to the new OpenTelemetry-based `@sentry/node` package.
1 parent d2005ba commit b0e1db0

File tree

14 files changed

+111
-103
lines changed

14 files changed

+111
-103
lines changed

dev-packages/e2e-tests/test-applications/node-exports-test-app/scripts/consistentExports.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ const DEPENDENTS: Dependent[] = [
9898
},
9999
{
100100
package: '@sentry/sveltekit',
101-
compareWith: nodeExperimentalExports,
101+
compareWith: nodeExports,
102102
exports: Object.keys(SentrySvelteKit),
103103
},
104104
];

packages/sveltekit/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
"dependencies": {
4040
"@sentry-internal/tracing": "8.0.0-alpha.2",
4141
"@sentry/core": "8.0.0-alpha.2",
42-
"@sentry/node-experimental": "8.0.0-alpha.2",
42+
"@sentry/node": "8.0.0-alpha.2",
43+
"@sentry/opentelemetry": "8.0.0-alpha.2",
4344
"@sentry/svelte": "8.0.0-alpha.2",
4445
"@sentry/types": "8.0.0-alpha.2",
4546
"@sentry/utils": "8.0.0-alpha.2",
@@ -68,7 +69,7 @@
6869
"fix": "eslint . --format stylish --fix",
6970
"lint": "eslint . --format stylish",
7071
"test": "yarn test:unit",
71-
"test:unit": "vitest run",
72+
"test:unit": "vitest run --outputDiffMaxLines=2000",
7273
"test:watch": "vitest --watch",
7374
"yalc:publish": "ts-node ../../scripts/prepack.ts && yalc publish build --push --sig"
7475
},

packages/sveltekit/src/index.types.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,20 @@ export declare function handleErrorWithSentry<T extends HandleClientError | Hand
3636
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3737
export declare function wrapLoadWithSentry<T extends (...args: any) => any>(origLoad: T): T;
3838

39-
// We export a merged Integrations object so that users can (at least typing-wise) use all integrations everywhere.
40-
// eslint-disable-next-line deprecation/deprecation
41-
export declare const Integrations: typeof clientSdk.Integrations & typeof serverSdk.Integrations;
42-
4339
export declare const linkedErrorsIntegration: typeof clientSdk.linkedErrorsIntegration;
4440
export declare const contextLinesIntegration: typeof clientSdk.contextLinesIntegration;
4541

4642
export declare const getDefaultIntegrations: (options: Options) => Integration[];
4743
export declare const defaultStackParser: StackParser;
4844

45+
export declare const getClient: typeof clientSdk.getClient;
46+
// eslint-disable-next-line deprecation/deprecation
47+
export declare const getCurrentHub: typeof clientSdk.getCurrentHub;
48+
// eslint-disable-next-line deprecation/deprecation
49+
export declare const makeMain: typeof clientSdk.makeMain;
4950
export declare function close(timeout?: number | undefined): PromiseLike<boolean>;
5051
export declare function flush(timeout?: number | undefined): PromiseLike<boolean>;
5152

53+
export declare const continueTrace: typeof clientSdk.continueTrace;
54+
5255
export declare const metrics: typeof clientSdk.metrics & typeof serverSdk.metrics;

packages/sveltekit/src/server/handle.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import {
22
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
33
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
4-
continueTrace,
54
getActiveSpan,
6-
getDynamicSamplingContextFromSpan,
75
getRootSpan,
86
setHttpStatus,
97
spanToTraceHeader,
108
withIsolationScope,
119
} from '@sentry/core';
1210
import { startSpan } from '@sentry/core';
13-
import { captureException } from '@sentry/node-experimental';
11+
import { captureException, continueTrace } from '@sentry/node';
1412
import type { Span } from '@sentry/types';
1513
import { dynamicSamplingContextToSentryBaggageHeader, objectify } from '@sentry/utils';
1614
import type { Handle, ResolveOptions } from '@sveltejs/kit';
1715

16+
import { getDynamicSamplingContextFromSpan } from '@sentry/opentelemetry';
17+
1818
import { isHttpError, isRedirect } from '../common/utils';
1919
import { flushIfServerless, getTracePropagationData } from './utils';
2020

@@ -149,9 +149,10 @@ export function sentryHandle(handlerOptions?: SentryHandleOptions): Handle {
149149
};
150150

151151
const sentryRequestHandler: Handle = input => {
152-
// if there is an active transaction, we know that this handle call is nested and hence
153-
// we don't create a new domain for it. If we created one, nested server calls would
154-
// create new transactions instead of adding a child span to the currently active span.
152+
// if there is an active span, we know that this handle call is nested and hence
153+
// we don't create a new execution context for it.
154+
// If we created one, nested server calls would create new root span instead
155+
// of adding a child span to the currently active span.
155156
if (getActiveSpan()) {
156157
return instrumentHandle(input, options);
157158
}
@@ -181,6 +182,7 @@ async function instrumentHandle(
181182
attributes: {
182183
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.sveltekit',
183184
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: event.route?.id ? 'route' : 'url',
185+
'http.method': event.request.method,
184186
},
185187
name: `${event.request.method} ${event.route?.id || event.url.pathname}`,
186188
},

packages/sveltekit/src/server/handleError.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { captureException } from '@sentry/node-experimental';
1+
import { captureException } from '@sentry/node';
22
import type { HandleServerError } from '@sveltejs/kit';
33

44
import { flushIfServerless } from './utils';

packages/sveltekit/src/server/index.ts

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
// Node SDK exports
2-
// Unfortunately, we cannot `export * from '@sentry/node-experimental'` because in prod builds,
2+
// Unfortunately, we cannot `export * from '@sentry/node'` because in prod builds,
33
// Vite puts these exports into a `default` property (Sentry.default) rather than
44
// on the top - level namespace.
55
// Hence, we export everything from the Node SDK explicitly:
66
export {
7-
// eslint-disable-next-line deprecation/deprecation
8-
addGlobalEventProcessor,
97
addEventProcessor,
108
addBreadcrumb,
119
addIntegration,
@@ -15,10 +13,6 @@ export {
1513
captureCheckIn,
1614
withMonitor,
1715
createTransport,
18-
// eslint-disable-next-line deprecation/deprecation
19-
getActiveTransaction,
20-
// eslint-disable-next-line deprecation/deprecation
21-
getCurrentHub,
2216
getClient,
2317
isInitialized,
2418
getCurrentScope,
@@ -41,7 +35,6 @@ export {
4135
setHttpStatus,
4236
withScope,
4337
withIsolationScope,
44-
autoDiscoverNodePerformanceMonitoringIntegrations,
4538
makeNodeTransport,
4639
getDefaultIntegrations,
4740
defaultStackParser,
@@ -51,7 +44,6 @@ export {
5144
addRequestDataToEvent,
5245
DEFAULT_USER_INCLUDES,
5346
extractRequestData,
54-
Integrations,
5547
consoleIntegration,
5648
onUncaughtExceptionIntegration,
5749
onUnhandledRejectionIntegration,
@@ -63,7 +55,6 @@ export {
6355
functionToStringIntegration,
6456
inboundFiltersIntegration,
6557
linkedErrorsIntegration,
66-
Handlers,
6758
setMeasurement,
6859
getActiveSpan,
6960
getRootSpan,
@@ -75,16 +66,15 @@ export {
7566
cron,
7667
parameterize,
7768
createGetModuleFromFilename,
78-
hapiErrorPlugin,
7969
metrics,
8070
SEMANTIC_ATTRIBUTE_SENTRY_OP,
8171
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
8272
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
8373
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
84-
} from '@sentry/node-experimental';
74+
} from '@sentry/node';
8575

8676
// We can still leave this for the carrier init and type exports
87-
export * from '@sentry/node-experimental';
77+
export * from '@sentry/node';
8878

8979
// -------------------------
9080
// SvelteKit SDK exports:

packages/sveltekit/src/server/load.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import {
22
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
33
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
4+
captureException,
45
continueTrace,
56
startSpan,
6-
} from '@sentry/core';
7-
import { captureException } from '@sentry/node-experimental';
7+
} from '@sentry/node';
88
import { addNonEnumerableProperty, objectify } from '@sentry/utils';
99
import type { LoadEvent, ServerLoadEvent } from '@sveltejs/kit';
1010

packages/sveltekit/src/server/sdk.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { applySdkMetadata, setTag } from '@sentry/core';
2-
import type { NodeOptions } from '@sentry/node-experimental';
3-
import { getDefaultIntegrations as getDefaultNodeIntegrations } from '@sentry/node-experimental';
4-
import { init as initNodeSdk } from '@sentry/node-experimental';
2+
import type { NodeOptions } from '@sentry/node';
3+
import { getDefaultIntegrations as getDefaultNodeIntegrations } from '@sentry/node';
4+
import { init as initNodeSdk } from '@sentry/node';
55

66
import { rewriteFramesIntegration } from './rewriteFramesIntegration';
77

packages/sveltekit/src/server/utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { flush } from '@sentry/node-experimental';
1+
import { flush } from '@sentry/node';
22
import { logger } from '@sentry/utils';
33
import type { RequestEvent } from '@sveltejs/kit';
44

packages/sveltekit/src/vite/sourceMaps.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as child_process from 'child_process';
22
import * as fs from 'fs';
33
import * as path from 'path';
4-
import { getSentryRelease } from '@sentry/node-experimental';
4+
import { getSentryRelease } from '@sentry/node';
55
import { escapeStringForRegex, uuid4 } from '@sentry/utils';
66
import type { SentryVitePluginOptions } from '@sentry/vite-plugin';
77
import { sentryVitePlugin } from '@sentry/vite-plugin';

packages/sveltekit/test/server/handle.test.ts

+20-6
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import {
66
spanIsSampled,
77
spanToJSON,
88
} from '@sentry/core';
9-
import { NodeClient, setCurrentClient } from '@sentry/node-experimental';
10-
import * as SentryNode from '@sentry/node-experimental';
11-
import type { Span } from '@sentry/types';
9+
import { NodeClient, setCurrentClient } from '@sentry/node';
10+
import * as SentryNode from '@sentry/node';
11+
import type { EventEnvelopeHeaders, Span } from '@sentry/types';
1212
import type { Handle } from '@sveltejs/kit';
1313
import { redirect } from '@sveltejs/kit';
1414
import { vi } from 'vitest';
@@ -43,6 +43,7 @@ function mockEvent(override: Record<string, unknown> = {}): Parameters<Handle>[0
4343
isDataRequest: false,
4444

4545
...override,
46+
isSubRequest: false,
4647
};
4748

4849
return event;
@@ -103,7 +104,7 @@ beforeEach(() => {
103104
mockCaptureException.mockClear();
104105
});
105106

106-
describe('handleSentry', () => {
107+
describe('sentryHandle', () => {
107108
describe.each([
108109
// isSync, isError, expectedResponse
109110
[Type.Sync, true, undefined],
@@ -117,6 +118,7 @@ describe('handleSentry', () => {
117118
response = await sentryHandle()({ event: mockEvent(), resolve: resolve(type, isError) });
118119
} catch (e) {
119120
expect(e).toBeInstanceOf(Error);
121+
// @ts-expect-error - this is fine
120122
expect(e.message).toEqual(type);
121123
}
122124

@@ -197,7 +199,7 @@ describe('handleSentry', () => {
197199
);
198200
});
199201

200-
it('creates a transaction from sentry-trace header', async () => {
202+
it("creates a transaction from sentry-trace header but doesn't populate a new DSC", async () => {
201203
const event = mockEvent({
202204
request: {
203205
headers: {
@@ -219,6 +221,11 @@ describe('handleSentry', () => {
219221
}
220222
});
221223

224+
let envelopeHeaders: EventEnvelopeHeaders | undefined = undefined;
225+
client.on('beforeEnvelope', env => {
226+
envelopeHeaders = env[0] as EventEnvelopeHeaders;
227+
});
228+
222229
try {
223230
await sentryHandle()({ event, resolve: resolve(type, isError) });
224231
} catch (e) {
@@ -229,6 +236,7 @@ describe('handleSentry', () => {
229236
expect(_span!.spanContext().traceId).toEqual('1234567890abcdef1234567890abcdef');
230237
expect(spanToJSON(_span!).parent_span_id).toEqual('1234567890abcdef');
231238
expect(spanIsSampled(_span!)).toEqual(true);
239+
expect(envelopeHeaders!.trace).toEqual({});
232240
});
233241

234242
it('creates a transaction with dynamic sampling context from baggage header', async () => {
@@ -261,14 +269,19 @@ describe('handleSentry', () => {
261269
}
262270
});
263271

272+
let envelopeHeaders: EventEnvelopeHeaders | undefined = undefined;
273+
client.on('beforeEnvelope', env => {
274+
envelopeHeaders = env[0] as EventEnvelopeHeaders;
275+
});
276+
264277
try {
265278
await sentryHandle()({ event, resolve: resolve(type, isError) });
266279
} catch (e) {
267280
//
268281
}
269282

270283
expect(_span!).toBeDefined();
271-
expect(_span.metadata.dynamicSamplingContext).toEqual({
284+
expect(envelopeHeaders!.trace).toEqual({
272285
environment: 'production',
273286
release: '1.0.0',
274287
public_key: 'dogsarebadatkeepingsecrets',
@@ -312,6 +325,7 @@ describe('handleSentry', () => {
312325
await sentryHandle()({ event, resolve: mockResolve });
313326
} catch (e) {
314327
expect(e).toBeInstanceOf(Error);
328+
// @ts-expect-error - this is fine
315329
expect(e.message).toEqual(type);
316330
}
317331

packages/sveltekit/test/server/handleError.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as SentryNode from '@sentry/node-experimental';
1+
import * as SentryNode from '@sentry/node';
22
import type { HandleServerError, RequestEvent } from '@sveltejs/kit';
33
import { vi } from 'vitest';
44

0 commit comments

Comments
 (0)