Skip to content

Commit 470d4ec

Browse files
authored
Merge pull request #14502 from getsentry/prepare-release/8.41.0
meta(changelog): Update changelog for 8.41.0
2 parents 0d1f1f0 + f7289c4 commit 470d4ec

File tree

115 files changed

+2778
-1332
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+2778
-1332
lines changed

.github/dependency-review-config.yml

+3-1
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

.github/workflows/canary.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ env:
1414

1515
CACHED_BUILD_PATHS: |
1616
${{ github.workspace }}/packages/*/*.tgz
17-
${{ github.workspace }}/dev-packages/test-utils/build
1817
${{ github.workspace }}/node_modules
1918
${{ github.workspace }}/packages/*/node_modules
2019
${{ github.workspace }}/dev-packages/*/node_modules
21-
${{ github.workspace }}/packages/utils/build
20+
${{ github.workspace }}/dev-packages/*/build
21+
${{ github.workspace }}/packages/*/build
2222
2323
permissions:
2424
contents: read

.size-limit.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module.exports = [
4040
path: 'packages/browser/build/npm/esm/index.js',
4141
import: createImport('init', 'browserTracingIntegration'),
4242
gzip: true,
43-
limit: '36.5 KB',
43+
limit: '37.5 KB',
4444
},
4545
{
4646
name: '@sentry/browser (incl. Tracing, Replay)',
@@ -124,22 +124,22 @@ module.exports = [
124124
import: createImport('init', 'ErrorBoundary', 'reactRouterV6BrowserTracingIntegration'),
125125
ignore: ['react/jsx-runtime'],
126126
gzip: true,
127-
limit: '39.5 KB',
127+
limit: '40.5 KB',
128128
},
129129
// Vue SDK (ESM)
130130
{
131131
name: '@sentry/vue',
132132
path: 'packages/vue/build/esm/index.js',
133133
import: createImport('init'),
134134
gzip: true,
135-
limit: '28 KB',
135+
limit: '29 KB',
136136
},
137137
{
138138
name: '@sentry/vue (incl. Tracing)',
139139
path: 'packages/vue/build/esm/index.js',
140140
import: createImport('init', 'browserTracingIntegration'),
141141
gzip: true,
142-
limit: '38.5 KB',
142+
limit: '39.5 KB',
143143
},
144144
// Svelte SDK (ESM)
145145
{
@@ -187,7 +187,7 @@ module.exports = [
187187
path: createCDNPath('bundle.tracing.min.js'),
188188
gzip: false,
189189
brotli: false,
190-
limit: '113 KB',
190+
limit: '120 KB',
191191
},
192192
{
193193
name: 'CDN Bundle (incl. Tracing, Replay) - uncompressed',
@@ -219,7 +219,7 @@ module.exports = [
219219
import: createImport('init'),
220220
ignore: ['$app/stores'],
221221
gzip: true,
222-
limit: '37 KB',
222+
limit: '38 KB',
223223
},
224224
// Node SDK (ESM)
225225
{

CHANGELOG.md

+94
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,100 @@
1010

1111
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
1212

13+
## 8.41.0
14+
15+
### Important Changes
16+
17+
- **meta(nuxt): Require minimum Nuxt v3.7.0 ([#14473](https://github.com/getsentry/sentry-javascript/pull/14473))**
18+
19+
We formalized that the Nuxt SDK is at minimum compatible with Nuxt version 3.7.0 and above.
20+
Additionally, the SDK requires the implicit `nitropack` dependency to satisfy version `^2.6.1` and `ofetch` to satisfy `^1.3.3`.
21+
It is recommended to check your lock-files and manually upgrade these dependencies if they don't match the version ranges.
22+
23+
### Deprecations
24+
25+
We are deprecating a few APIs which will be removed in the next major.
26+
27+
The following deprecations will _potentially_ affect you:
28+
29+
- **feat(core): Update & deprecate `undefined` option handling ([#14450](https://github.com/getsentry/sentry-javascript/pull/14450))**
30+
31+
In the next major version we will change how passing `undefined` to `tracesSampleRate` / `tracesSampler` / `enableTracing` will behave.
32+
33+
Currently, doing the following:
34+
35+
```ts
36+
Sentry.init({
37+
tracesSampleRate: undefined,
38+
});
39+
```
40+
41+
Will result in tracing being _enabled_ (although no spans will be generated) because the `tracesSampleRate` key is present in the options object.
42+
In the next major version, this behavior will be changed so that passing `undefined` (or rather having a `tracesSampleRate` key) will result in tracing being disabled, the same as not passing the option at all.
43+
If you are currently relying on `undefined` being passed, and and thus have tracing enabled, it is recommended to update your config to set e.g. `tracesSampleRate: 0` instead, which will also enable tracing in v9.
44+
45+
The same applies to `tracesSampler` and `enableTracing`.
46+
47+
- **feat(core): Log warnings when returning `null` in `beforeSendSpan` ([#14433](https://github.com/getsentry/sentry-javascript/pull/14433))**
48+
49+
Currently, the `beforeSendSpan` option in `Sentry.init()` allows you to drop individual spans from a trace by returning `null` from the hook.
50+
Since this API lends itself to creating "gaps" inside traces, we decided to change how this API will work in the next major version.
51+
52+
With the next major version the `beforeSendSpan` API can only be used to mutate spans, but no longer to drop them.
53+
With this release the SDK will warn you if you are using this API to drop spans.
54+
Instead, it is recommended to configure instrumentation (i.e. integrations) directly to control what spans are created.
55+
56+
Additionally, with the next major version, root spans will also be passed to `beforeSendSpan`.
57+
58+
- **feat(utils): Deprecate `@sentry/utils` ([#14431](https://github.com/getsentry/sentry-javascript/pull/14431))**
59+
60+
With the next major version the `@sentry/utils` package will be merged into the `@sentry/core` package.
61+
It is therefore no longer recommended to use the `@sentry/utils` package.
62+
63+
- **feat(vue): Deprecate configuring Vue tracing options anywhere else other than through the `vueIntegration`'s `tracingOptions` option ([#14385](https://github.com/getsentry/sentry-javascript/pull/14385))**
64+
65+
Currently it is possible to configure tracing options in various places in the Sentry Vue SDK:
66+
67+
- In `Sentry.init()`
68+
- Inside `tracingOptions` in `Sentry.init()`
69+
- In the `vueIntegration()` options
70+
- Inside `tracingOptions` in the `vueIntegration()` options
71+
72+
Because this is a bit messy and confusing to document, the only recommended way to configure tracing options going forward is through the `tracingOptions` in the `vueIntegration()`.
73+
The other means of configuration will be removed in the next major version of the SDK.
74+
75+
- **feat: Deprecate `registerEsmLoaderHooks.include` and `registerEsmLoaderHooks.exclude` ([#14486](https://github.com/getsentry/sentry-javascript/pull/14486))**
76+
77+
Currently it is possible to define `registerEsmLoaderHooks.include` and `registerEsmLoaderHooks.exclude` options in `Sentry.init()` to only apply ESM loader hooks to a subset of modules.
78+
This API served as an escape hatch in case certain modules are incompatible with ESM loader hooks.
79+
80+
Since this API was introduced, a way was found to only wrap modules that there exists instrumentation for (meaning a vetted list).
81+
To only wrap modules that have instrumentation, it is recommended to instead set `registerEsmLoaderHooks.onlyIncludeInstrumentedModules` to `true`.
82+
83+
Note that `onlyIncludeInstrumentedModules: true` will become the default behavior in the next major version and the `registerEsmLoaderHooks` will no longer accept fine-grained options.
84+
85+
The following deprecations will _most likely_ not affect you unless you are building an SDK yourself:
86+
87+
- feat(core): Deprecate `arrayify` ([#14405](https://github.com/getsentry/sentry-javascript/pull/14405))
88+
- feat(core): Deprecate `flatten` ([#14454](https://github.com/getsentry/sentry-javascript/pull/14454))
89+
- feat(core): Deprecate `urlEncode` ([#14406](https://github.com/getsentry/sentry-javascript/pull/14406))
90+
- feat(core): Deprecate `validSeverityLevels` ([#14407](https://github.com/getsentry/sentry-javascript/pull/14407))
91+
- feat(core/utils): Deprecate `getNumberOfUrlSegments` ([#14458](https://github.com/getsentry/sentry-javascript/pull/14458))
92+
- feat(utils): Deprecate `memoBuilder`, `BAGGAGE_HEADER_NAME`, and `makeFifoCache` ([#14434](https://github.com/getsentry/sentry-javascript/pull/14434))
93+
- feat(utils/core): Deprecate `addRequestDataToEvent` and `extractRequestData` ([#14430](https://github.com/getsentry/sentry-javascript/pull/14430))
94+
95+
### Other Changes
96+
97+
- feat: Streamline `sentry-trace`, `baggage` and DSC handling ([#14364](https://github.com/getsentry/sentry-javascript/pull/14364))
98+
- feat(core): Further optimize debug ID parsing ([#14365](https://github.com/getsentry/sentry-javascript/pull/14365))
99+
- feat(node): Add `openTelemetryInstrumentations` option ([#14484](https://github.com/getsentry/sentry-javascript/pull/14484))
100+
- feat(nuxt): Add filter for not found source maps (devtools) ([#14437](https://github.com/getsentry/sentry-javascript/pull/14437))
101+
- feat(nuxt): Only delete public source maps ([#14438](https://github.com/getsentry/sentry-javascript/pull/14438))
102+
- fix(nextjs): Don't report `NEXT_REDIRECT` from browser ([#14440](https://github.com/getsentry/sentry-javascript/pull/14440))
103+
- perf(opentelemetry): Bucket spans for cleanup ([#14154](https://github.com/getsentry/sentry-javascript/pull/14154))
104+
105+
Work in this release was contributed by @NEKOYASAN and @fmorett. Thank you for your contributions!
106+
13107
## 8.40.0
14108

15109
### Important Changes

dev-packages/browser-integration-tests/suites/integrations/ContextLines/noAddedLines/test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ sentryTest('should not add source context lines to errors from script files', as
77
const url = await getLocalTestUrl({ testDir: __dirname });
88

99
const eventReqPromise = waitForErrorRequestOnUrl(page, url);
10+
await page.waitForFunction('window.Sentry');
1011

1112
const clickPromise = page.locator('#script-error-btn').click();
1213

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Sentry.withScope(() => {
2+
Sentry.startSpan({ name: 'test_span_1' }, () => undefined);
3+
Sentry.startSpan({ name: 'test_span_2' }, () => undefined);
4+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { expect } from '@playwright/test';
2+
3+
import type { TransactionEvent } from '@sentry/types';
4+
import { sentryTest } from '../../../../utils/fixtures';
5+
import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../../utils/helpers';
6+
7+
sentryTest(
8+
'should send manually started parallel root spans outside of root context',
9+
async ({ getLocalTestUrl, page }) => {
10+
if (shouldSkipTracingTest()) {
11+
sentryTest.skip();
12+
}
13+
14+
const url = await getLocalTestUrl({ testDir: __dirname });
15+
16+
const transaction1ReqPromise = waitForTransactionRequest(page, event => event.transaction === 'test_span_1');
17+
const transaction2ReqPromise = waitForTransactionRequest(page, event => event.transaction === 'test_span_2');
18+
19+
await page.goto(url);
20+
21+
const [transaction1Req, transaction2Req] = await Promise.all([transaction1ReqPromise, transaction2ReqPromise]);
22+
23+
const transaction1 = envelopeRequestParser<TransactionEvent>(transaction1Req);
24+
const transaction2 = envelopeRequestParser<TransactionEvent>(transaction2Req);
25+
26+
expect(transaction1).toBeDefined();
27+
expect(transaction2).toBeDefined();
28+
29+
const trace1Id = transaction1.contexts?.trace?.trace_id;
30+
const trace2Id = transaction2.contexts?.trace?.trace_id;
31+
32+
expect(trace1Id).toBeDefined();
33+
expect(trace2Id).toBeDefined();
34+
35+
// We use the same traceID from the root propagation context here
36+
expect(trace1Id).toBe(trace2Id);
37+
38+
expect(transaction1.contexts?.trace?.parent_span_id).toBeUndefined();
39+
expect(transaction2.contexts?.trace?.parent_span_id).toBeUndefined();
40+
},
41+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Sentry.getCurrentScope().setPropagationContext({
2+
parentSpanId: '1234567890123456',
3+
spanId: '123456789012345x',
4+
traceId: '12345678901234567890123456789012',
5+
});
6+
7+
Sentry.startSpan({ name: 'test_span_1' }, () => undefined);
8+
Sentry.startSpan({ name: 'test_span_2' }, () => undefined);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { expect } from '@playwright/test';
2+
3+
import type { TransactionEvent } from '@sentry/types';
4+
import { sentryTest } from '../../../../utils/fixtures';
5+
import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../../utils/helpers';
6+
7+
sentryTest(
8+
'should send manually started parallel root spans in root context with parentSpanId',
9+
async ({ getLocalTestUrl, page }) => {
10+
if (shouldSkipTracingTest()) {
11+
sentryTest.skip();
12+
}
13+
14+
const url = await getLocalTestUrl({ testDir: __dirname });
15+
16+
const transaction1ReqPromise = waitForTransactionRequest(page, event => event.transaction === 'test_span_1');
17+
const transaction2ReqPromise = waitForTransactionRequest(page, event => event.transaction === 'test_span_2');
18+
19+
await page.goto(url);
20+
21+
const [transaction1Req, transaction2Req] = await Promise.all([transaction1ReqPromise, transaction2ReqPromise]);
22+
23+
const transaction1 = envelopeRequestParser<TransactionEvent>(transaction1Req);
24+
const transaction2 = envelopeRequestParser<TransactionEvent>(transaction2Req);
25+
26+
expect(transaction1).toBeDefined();
27+
expect(transaction2).toBeDefined();
28+
29+
const trace1Id = transaction1.contexts?.trace?.trace_id;
30+
const trace2Id = transaction2.contexts?.trace?.trace_id;
31+
32+
expect(trace1Id).toBe('12345678901234567890123456789012');
33+
expect(trace2Id).toBe('12345678901234567890123456789012');
34+
35+
expect(transaction1.contexts?.trace?.parent_span_id).toBe('1234567890123456');
36+
expect(transaction2.contexts?.trace?.parent_span_id).toBe('1234567890123456');
37+
},
38+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Sentry.startSpan({ name: 'test_span_1' }, () => undefined);
2+
Sentry.startSpan({ name: 'test_span_2' }, () => undefined);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { expect } from '@playwright/test';
2+
3+
import type { TransactionEvent } from '@sentry/types';
4+
import { sentryTest } from '../../../../utils/fixtures';
5+
import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../../utils/helpers';
6+
7+
sentryTest('should send manually started parallel root spans in root context', async ({ getLocalTestUrl, page }) => {
8+
if (shouldSkipTracingTest()) {
9+
sentryTest.skip();
10+
}
11+
12+
const url = await getLocalTestUrl({ testDir: __dirname });
13+
14+
const transaction1ReqPromise = waitForTransactionRequest(page, event => event.transaction === 'test_span_1');
15+
const transaction2ReqPromise = waitForTransactionRequest(page, event => event.transaction === 'test_span_2');
16+
17+
await page.goto(url);
18+
19+
const [transaction1Req, transaction2Req] = await Promise.all([transaction1ReqPromise, transaction2ReqPromise]);
20+
21+
const transaction1 = envelopeRequestParser<TransactionEvent>(transaction1Req);
22+
const transaction2 = envelopeRequestParser<TransactionEvent>(transaction2Req);
23+
24+
expect(transaction1).toBeDefined();
25+
expect(transaction2).toBeDefined();
26+
27+
const trace1Id = transaction1.contexts?.trace?.trace_id;
28+
const trace2Id = transaction2.contexts?.trace?.trace_id;
29+
30+
expect(trace1Id).toBeDefined();
31+
expect(trace2Id).toBeDefined();
32+
33+
// We use the same traceID from the root propagation context here
34+
expect(trace1Id).toBe(trace2Id);
35+
36+
expect(transaction1.contexts?.trace?.parent_span_id).toBeUndefined();
37+
expect(transaction2.contexts?.trace?.parent_span_id).toBeUndefined();
38+
});

dev-packages/browser-integration-tests/utils/helpers.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
Event,
88
EventEnvelope,
99
EventEnvelopeHeaders,
10+
TransactionEvent,
1011
} from '@sentry/types';
1112

1213
export const envelopeUrlRegex = /\.sentry\.io\/api\/\d+\/envelope\//;
@@ -224,7 +225,10 @@ export function waitForErrorRequest(page: Page, callback?: (event: Event) => boo
224225
});
225226
}
226227

227-
export function waitForTransactionRequest(page: Page): Promise<Request> {
228+
export function waitForTransactionRequest(
229+
page: Page,
230+
callback?: (event: TransactionEvent) => boolean,
231+
): Promise<Request> {
228232
return page.waitForRequest(req => {
229233
const postData = req.postData();
230234
if (!postData) {
@@ -234,7 +238,15 @@ export function waitForTransactionRequest(page: Page): Promise<Request> {
234238
try {
235239
const event = envelopeRequestParser(req);
236240

237-
return event.type === 'transaction';
241+
if (event.type !== 'transaction') {
242+
return false;
243+
}
244+
245+
if (callback) {
246+
return callback(event as TransactionEvent);
247+
}
248+
249+
return true;
238250
} catch {
239251
return false;
240252
}

dev-packages/e2e-tests/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"clean": "rimraf tmp node_modules pnpm-lock.yaml && yarn clean:test-applications",
1717
"ci:build-matrix": "ts-node ./lib/getTestMatrix.ts",
1818
"ci:build-matrix-optional": "ts-node ./lib/getTestMatrix.ts --optional=true",
19-
"clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.sveltekit,pnpm-lock.yaml} .last-run.json && pnpm store prune"
19+
"clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.sveltekit,pnpm-lock.yaml,.last-run.json,test-results} && pnpm store prune"
2020
},
2121
"devDependencies": {
2222
"@types/glob": "8.0.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default function RedirectDestinationPage() {
2+
return (
3+
<div>
4+
<h1>Redirect Destination</h1>
5+
</div>
6+
);
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { redirect } from 'next/navigation';
2+
3+
async function redirectAction() {
4+
'use server';
5+
6+
redirect('/redirect/destination');
7+
}
8+
9+
export default function RedirectOriginPage() {
10+
return (
11+
<>
12+
{/* @ts-ignore */}
13+
<form action={redirectAction}>
14+
<button type="submit">Redirect me</button>
15+
</form>
16+
</>
17+
);
18+
}

0 commit comments

Comments
 (0)