Skip to content

Commit 65d798d

Browse files
authored
Merge branch 'develop' into cg/deprecate-astro-runtime-options
2 parents dde0868 + 3e7969f commit 65d798d

File tree

17 files changed

+129
-162
lines changed

17 files changed

+129
-162
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
fail-on-severity: 'high'
22
allow-ghsas:
33
# dependency review does not allow specific file exclusions
4-
# we use an older version of NextJS in our tests and thus need to
4+
# we use an older version of NextJS in our tests and thus need to
55
# exclude this
66
# once our minimum supported version is over 14.1.1 this can be removed
77
- GHSA-fr5h-rqp8-mj6g
8+
# we need this for an E2E test for the minimum required version of Nuxt 3.7.0
9+
- GHSA-v784-fjjh-f8r4

dev-packages/e2e-tests/test-applications/nuxt-3-min/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nuxt-3-min",
3-
"description": "E2E test app for the minimum nuxt 3 version our nuxt SDK supports.",
3+
"description": "E2E test app for the minimum Nuxt 3 version our Nuxt SDK supports.",
44
"private": true,
55
"type": "module",
66
"scripts": {
@@ -16,15 +16,15 @@
1616
},
1717
"dependencies": {
1818
"@sentry/nuxt": "latest || *",
19-
"nuxt": "3.13.2"
19+
"nuxt": "3.7.0"
2020
},
2121
"devDependencies": {
2222
"@nuxt/test-utils": "^3.14.1",
2323
"@playwright/test": "^1.44.1",
2424
"@sentry-internal/test-utils": "link:../../../test-utils"
2525
},
2626
"overrides": {
27-
"nitropack": "2.9.7",
28-
"@vercel/nft": "^0.27.4"
27+
"nitropack": "2.10.0",
28+
"ofetch": "1.4.0"
2929
}
3030
}

dev-packages/e2e-tests/test-applications/nuxt-3/package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,11 @@
1515
},
1616
"dependencies": {
1717
"@sentry/nuxt": "latest || *",
18-
"nuxt": "^3.13.1"
18+
"nuxt": "^3.14.0"
1919
},
2020
"devDependencies": {
2121
"@nuxt/test-utils": "^3.14.1",
2222
"@playwright/test": "^1.44.1",
2323
"@sentry-internal/test-utils": "link:../../../test-utils"
24-
},
25-
"overrides": {
26-
"@vercel/nft": "0.27.4"
2724
}
2825
}

dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ afterAll(() => {
55
});
66

77
const esmWarning =
8-
'[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or use version 7.x of the Sentry Node.js SDK.';
8+
'[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or upgrade your Node.js version.';
99

1010
test("warns if using ESM on Node.js versions that don't support `register()`", async () => {
1111
const nodeMajorVersion = Number(process.versions.node.split('.')[0]);

docs/migration/draft-v9-migration-guide.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,14 @@
8585
});
8686
```
8787

88+
## `@sentry/astro`
89+
90+
- Deprecated passing `dsn`, `release`, `environment`, `sampleRate`, `tracesSampleRate`, `replaysSessionSampleRate` to the integration. Use the runtime-specific `Sentry.init()` calls for passing these options instead.
91+
8892
## Server-side SDKs (`@sentry/node` and all dependents)
8993

9094
- Deprecated `processThreadBreadcrumbIntegration` in favor of `childProcessIntegration`. Functionally they are the same.
9195
- Deprecated `nestIntegration`. Use the NestJS SDK (`@sentry/nestjs`) instead.
9296
- Deprecated `setupNestErrorHandler`. Use the NestJS SDK (`@sentry/nestjs`) instead.
93-
94-
## `@sentry/astro`
95-
96-
- Deprecated passing `dsn`, `release`, `environment`, `sampleRate`, `tracesSampleRate`, `replaysSessionSampleRate` to the integration. Use the runtime-specific `Sentry.init()` calls for passing these options instead.
97+
- Deprecated `registerEsmLoaderHooks.include` and `registerEsmLoaderHooks.exclude`. Set `onlyIncludeInstrumentedModules: true` instead.
98+
- `registerEsmLoaderHooks` will only accept `true | false | undefined` in the future. The SDK will default to wrapping modules that are used as part of OpenTelemetry Instrumentation.

packages/core/src/utils-hoist/debug-ids.ts

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
import type { DebugImage, StackFrame, StackParser } from '@sentry/types';
1+
import type { DebugImage, StackParser } from '@sentry/types';
22
import { GLOBAL_OBJ } from './worldwide';
33

4-
const debugIdStackParserCache = new WeakMap<StackParser, Map<string, StackFrame[]>>();
4+
type StackString = string;
5+
type CachedResult = [string, string];
6+
7+
let parsedStackResults: Record<StackString, CachedResult> | undefined;
8+
let lastKeysCount: number | undefined;
9+
let cachedFilenameDebugIds: Record<string, string> | undefined;
510

611
/**
712
* Returns a map of filenames to debug identifiers.
@@ -12,38 +17,46 @@ export function getFilenameToDebugIdMap(stackParser: StackParser): Record<string
1217
return {};
1318
}
1419

15-
let debugIdStackFramesCache: Map<string, StackFrame[]>;
16-
const cachedDebugIdStackFrameCache = debugIdStackParserCache.get(stackParser);
17-
if (cachedDebugIdStackFrameCache) {
18-
debugIdStackFramesCache = cachedDebugIdStackFrameCache;
19-
} else {
20-
debugIdStackFramesCache = new Map<string, StackFrame[]>();
21-
debugIdStackParserCache.set(stackParser, debugIdStackFramesCache);
20+
const debugIdKeys = Object.keys(debugIdMap);
21+
22+
// If the count of registered globals hasn't changed since the last call, we
23+
// can just return the cached result.
24+
if (cachedFilenameDebugIds && debugIdKeys.length === lastKeysCount) {
25+
return cachedFilenameDebugIds;
2226
}
2327

28+
lastKeysCount = debugIdKeys.length;
29+
2430
// Build a map of filename -> debug_id.
25-
return Object.keys(debugIdMap).reduce<Record<string, string>>((acc, debugIdStackTrace) => {
26-
let parsedStack: StackFrame[];
31+
cachedFilenameDebugIds = debugIdKeys.reduce<Record<string, string>>((acc, stackKey) => {
32+
if (!parsedStackResults) {
33+
parsedStackResults = {};
34+
}
35+
36+
const result = parsedStackResults[stackKey];
2737

28-
const cachedParsedStack = debugIdStackFramesCache.get(debugIdStackTrace);
29-
if (cachedParsedStack) {
30-
parsedStack = cachedParsedStack;
38+
if (result) {
39+
acc[result[0]] = result[1];
3140
} else {
32-
parsedStack = stackParser(debugIdStackTrace);
33-
debugIdStackFramesCache.set(debugIdStackTrace, parsedStack);
34-
}
41+
const parsedStack = stackParser(stackKey);
3542

36-
for (let i = parsedStack.length - 1; i >= 0; i--) {
37-
const stackFrame = parsedStack[i];
38-
const file = stackFrame && stackFrame.filename;
43+
for (let i = parsedStack.length - 1; i >= 0; i--) {
44+
const stackFrame = parsedStack[i];
45+
const filename = stackFrame && stackFrame.filename;
46+
const debugId = debugIdMap[stackKey];
3947

40-
if (stackFrame && file) {
41-
acc[file] = debugIdMap[debugIdStackTrace] as string;
42-
break;
48+
if (filename && debugId) {
49+
acc[filename] = debugId;
50+
parsedStackResults[stackKey] = [filename, debugId];
51+
break;
52+
}
4353
}
4454
}
55+
4556
return acc;
4657
}, {});
58+
59+
return cachedFilenameDebugIds;
4760
}
4861

4962
/**
@@ -55,6 +68,10 @@ export function getDebugImagesForResources(
5568
): DebugImage[] {
5669
const filenameDebugIdMap = getFilenameToDebugIdMap(stackParser);
5770

71+
if (!filenameDebugIdMap) {
72+
return [];
73+
}
74+
5875
const images: DebugImage[] = [];
5976
for (const path of resource_paths) {
6077
if (path && filenameDebugIdMap[path]) {

packages/core/src/utils/prepareEvent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export function applyDebugIds(event: Event, stackParser: StackParser): void {
179179
event!.exception!.values!.forEach(exception => {
180180
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
181181
exception.stacktrace!.frames!.forEach(frame => {
182-
if (frame.filename) {
182+
if (filenameDebugIdMap && frame.filename) {
183183
frame.debug_id = filenameDebugIdMap[frame.filename];
184184
}
185185
});

packages/core/src/utils/traceData.ts

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,39 +44,12 @@ export function getTraceData(options: { span?: Span } = {}): SerializedTraceData
4444
return {};
4545
}
4646

47-
const validBaggage = isValidBaggageString(baggage);
48-
if (!validBaggage) {
49-
logger.warn('Invalid baggage data. Not returning "baggage" value');
50-
}
51-
5247
return {
5348
'sentry-trace': sentryTrace,
54-
...(validBaggage && { baggage }),
49+
baggage,
5550
};
5651
}
5752

58-
/**
59-
* Tests string against baggage spec as defined in:
60-
*
61-
* - W3C Baggage grammar: https://www.w3.org/TR/baggage/#definition
62-
* - RFC7230 token definition: https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
63-
*
64-
* exported for testing
65-
*/
66-
export function isValidBaggageString(baggage?: string): boolean {
67-
if (!baggage || !baggage.length) {
68-
return false;
69-
}
70-
const keyRegex = "[-!#$%&'*+.^_`|~A-Za-z0-9]+";
71-
const valueRegex = '[!#-+-./0-9:<=>?@A-Z\\[\\]a-z{-}]+';
72-
const spaces = '\\s*';
73-
// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- RegExp for readability, no user input
74-
const baggageRegex = new RegExp(
75-
`^${keyRegex}${spaces}=${spaces}${valueRegex}(${spaces},${spaces}${keyRegex}${spaces}=${spaces}${valueRegex})*$`,
76-
);
77-
return baggageRegex.test(baggage);
78-
}
79-
8053
/**
8154
* Get a sentry-trace header value for the given scope.
8255
*/

packages/core/test/lib/utils/traceData.test.ts

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
import { getAsyncContextStrategy } from '../../../src/asyncContext';
1414
import { freezeDscOnSpan } from '../../../src/tracing/dynamicSamplingContext';
1515

16-
import { isValidBaggageString } from '../../../src/utils/traceData';
1716
import type { TestClientOptions } from '../../mocks/client';
1817
import { TestClient, getDefaultTestClientOptions } from '../../mocks/client';
1918

@@ -281,75 +280,3 @@ describe('getTraceData', () => {
281280
expect(traceData).toEqual({});
282281
});
283282
});
284-
285-
describe('isValidBaggageString', () => {
286-
it.each([
287-
'sentry-environment=production',
288-
'sentry-environment=staging,sentry-public_key=key,sentry-trace_id=abc',
289-
// @ is allowed in values
290-
291-
// spaces are allowed around the delimiters
292-
'sentry-environment=staging , sentry-public_key=key ,[email protected]',
293-
'sentry-environment=staging , thirdparty=value ,[email protected]',
294-
// these characters are explicitly allowed for keys in the baggage spec:
295-
"!#$%&'*+-.^_`|~1234567890abcxyzABCXYZ=true",
296-
// special characters in values are fine (except for ",;\ - see other test)
297-
'key=(value)',
298-
'key=[{(value)}]',
299-
'key=some$value',
300-
'key=more#value',
301-
'key=max&value',
302-
'key=max:value',
303-
'key=x=value',
304-
])('returns true if the baggage string is valid (%s)', baggageString => {
305-
expect(isValidBaggageString(baggageString)).toBe(true);
306-
});
307-
308-
it.each([
309-
// baggage spec doesn't permit leading spaces
310-
' sentry-environment=production,sentry-publickey=key,sentry-trace_id=abc',
311-
// no spaces in keys or values
312-
'sentry-public key=key',
313-
'sentry-publickey=my key',
314-
// no delimiters ("(),/:;<=>?@[\]{}") in keys
315-
'asdf(x=value',
316-
'asdf)x=value',
317-
'asdf,x=value',
318-
'asdf/x=value',
319-
'asdf:x=value',
320-
'asdf;x=value',
321-
'asdf<x=value',
322-
'asdf>x=value',
323-
'asdf?x=value',
324-
'asdf@x=value',
325-
'asdf[x=value',
326-
'asdf]x=value',
327-
'asdf\\x=value',
328-
'asdf{x=value',
329-
'asdf}x=value',
330-
// no ,;\" in values
331-
'key=va,lue',
332-
'key=va;lue',
333-
'key=va\\lue',
334-
'key=va"lue"',
335-
// baggage headers can have properties but we currently don't support them
336-
'sentry-environment=production;prop1=foo;prop2=bar,nextkey=value',
337-
// no fishy stuff
338-
'absolutely not a valid baggage string',
339-
'val"/><script>alert("xss")</script>',
340-
'something"/>',
341-
'<script>alert("xss")</script>',
342-
'/>',
343-
'" onblur="alert("xss")',
344-
])('returns false if the baggage string is invalid (%s)', baggageString => {
345-
expect(isValidBaggageString(baggageString)).toBe(false);
346-
});
347-
348-
it('returns false if the baggage string is empty', () => {
349-
expect(isValidBaggageString('')).toBe(false);
350-
});
351-
352-
it('returns false if the baggage string is empty', () => {
353-
expect(isValidBaggageString(undefined)).toBe(false);
354-
});
355-
});

packages/node/src/integrations/anr/index.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as diagnosticsChannel from 'node:diagnostics_channel';
21
import { Worker } from 'node:worker_threads';
32
import { defineIntegration, getCurrentScope, getGlobalScope, getIsolationScope, mergeScopeData } from '@sentry/core';
43
import { GLOBAL_OBJ, getFilenameToDebugIdMap, logger } from '@sentry/core';
@@ -101,13 +100,6 @@ type AnrReturn = (options?: Partial<AnrIntegrationOptions>) => Integration & Anr
101100

102101
export const anrIntegration = defineIntegration(_anrIntegration) as AnrReturn;
103102

104-
function onModuleLoad(callback: () => void): void {
105-
// eslint-disable-next-line deprecation/deprecation
106-
diagnosticsChannel.channel('module.require.end').subscribe(() => callback());
107-
// eslint-disable-next-line deprecation/deprecation
108-
diagnosticsChannel.channel('module.import.asyncEnd').subscribe(() => callback());
109-
}
110-
111103
/**
112104
* Starts the ANR worker thread
113105
*
@@ -161,12 +153,6 @@ async function _startWorker(
161153
}
162154
}
163155

164-
let debugImages: Record<string, string> = getFilenameToDebugIdMap(initOptions.stackParser);
165-
166-
onModuleLoad(() => {
167-
debugImages = getFilenameToDebugIdMap(initOptions.stackParser);
168-
});
169-
170156
const worker = new Worker(new URL(`data:application/javascript;base64,${base64WorkerScript}`), {
171157
workerData: options,
172158
// We don't want any Node args to be passed to the worker
@@ -185,7 +171,7 @@ async function _startWorker(
185171
// serialized without making it a SerializedSession
186172
const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined;
187173
// message the worker to tell it the main event loop is still running
188-
worker.postMessage({ session, debugImages });
174+
worker.postMessage({ session, debugImages: getFilenameToDebugIdMap(initOptions.stackParser) });
189175
} catch (_) {
190176
//
191177
}

0 commit comments

Comments
 (0)