Skip to content

Commit b4eedd9

Browse files
authored
Merge branch 'develop' into instrument-langchain
2 parents 81f75c9 + 8e3afe2 commit b4eedd9

File tree

268 files changed

+5859
-1184
lines changed

Some content is hidden

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

268 files changed

+5859
-1184
lines changed

.github/workflows/canary.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,8 @@ jobs:
7676
build-command: 'test:build-canary'
7777
label: 'create-react-app (canary)'
7878
- test-application: 'nextjs-app-dir'
79-
build-command: 'test:build-canary'
80-
label: 'nextjs-app-dir (canary)'
81-
- test-application: 'nextjs-app-dir'
82-
build-command: 'test:build-latest'
83-
label: 'nextjs-app-dir (latest)'
79+
build-command: 'test:build-15'
80+
label: 'nextjs-app-dir (next@15)'
8481
- test-application: 'nextjs-13'
8582
build-command: 'test:build-latest'
8683
label: 'nextjs-13 (latest)'
@@ -90,12 +87,15 @@ jobs:
9087
- test-application: 'nextjs-14'
9188
build-command: 'test:build-latest'
9289
label: 'nextjs-14 (latest)'
93-
- test-application: 'nextjs-15'
94-
build-command: 'test:build-canary'
95-
label: 'nextjs-15 (canary)'
9690
- test-application: 'nextjs-15'
9791
build-command: 'test:build-latest'
9892
label: 'nextjs-15 (latest)'
93+
- test-application: 'nextjs-16'
94+
build-command: 'test:build-canary'
95+
label: 'nextjs-16 (canary)'
96+
- test-application: 'nextjs-16'
97+
build-command: 'test:build-canary-webpack'
98+
label: 'nextjs-16 (canary-webpack)'
9999
- test-application: 'nextjs-turbo'
100100
build-command: 'test:build-canary'
101101
label: 'nextjs-turbo (canary)'

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,6 @@ packages/gatsby/gatsby-node.d.ts
6161
# intellij
6262
*.iml
6363
/**/.wrangler/*
64+
65+
#junit reports
66+
packages/**/*.junit.xml

.size-limit.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ module.exports = [
3838
path: 'packages/browser/build/npm/esm/index.js',
3939
import: createImport('init', 'browserTracingIntegration'),
4040
gzip: true,
41-
limit: '40.7 KB',
41+
limit: '41 KB',
4242
},
4343
{
4444
name: '@sentry/browser (incl. Tracing, Replay)',
@@ -82,7 +82,7 @@ module.exports = [
8282
path: 'packages/browser/build/npm/esm/index.js',
8383
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
8484
gzip: true,
85-
limit: '96 KB',
85+
limit: '97 KB',
8686
},
8787
{
8888
name: '@sentry/browser (incl. Feedback)',
@@ -128,7 +128,7 @@ module.exports = [
128128
path: 'packages/vue/build/esm/index.js',
129129
import: createImport('init'),
130130
gzip: true,
131-
limit: '29 KB',
131+
limit: '30 KB',
132132
},
133133
{
134134
name: '@sentry/vue (incl. Tracing)',
@@ -183,7 +183,7 @@ module.exports = [
183183
path: createCDNPath('bundle.tracing.min.js'),
184184
gzip: false,
185185
brotli: false,
186-
limit: '123 KB',
186+
limit: '124 KB',
187187
},
188188
{
189189
name: 'CDN Bundle (incl. Tracing, Replay) - uncompressed',
@@ -206,7 +206,7 @@ module.exports = [
206206
import: createImport('init'),
207207
ignore: ['next/router', 'next/constants'],
208208
gzip: true,
209-
limit: '45 KB',
209+
limit: '46 KB',
210210
},
211211
// SvelteKit SDK (ESM)
212212
{

CHANGELOG.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,47 @@
44

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

7-
Work in this release was contributed by @seoyeon9888. Thank you for your contribution!
7+
Work in this release was contributed by @0xbad0c0d3. Thank you for your contribution!
8+
9+
## 10.20.0
10+
11+
### Important Changes
12+
13+
- **feat(flags): Add Growthbook integration ([#17440](https://github.com/getsentry/sentry-javascript/pull/17440))**
14+
15+
Adds a new Growthbook integration for feature flag support.
16+
17+
- **feat(solid): Add support for TanStack Router Solid ([#17735](https://github.com/getsentry/sentry-javascript/pull/17735))**
18+
19+
Adds support for TanStack Router in the Solid SDK, enabling better routing instrumentation for Solid applications.
20+
21+
- **feat(nextjs): Support native debugIds in turbopack ([#17853](https://github.com/getsentry/sentry-javascript/pull/17853))**
22+
23+
Adds support for native Debug IDs in Turbopack, improving source map resolution and error tracking for Next.js applications using Turbopack. Native Debug ID generation will be enabled automatically for compatible versions.
24+
25+
### Other Changes
26+
27+
- feat(nextjs): Prepare for next 16 bundler default ([#17868](https://github.com/getsentry/sentry-javascript/pull/17868))
28+
- feat(node): Capture `pino` logger name ([#17930](https://github.com/getsentry/sentry-javascript/pull/17930))
29+
- fix(browser): Ignore React 19.2+ component render measure entries ([#17905](https://github.com/getsentry/sentry-javascript/pull/17905))
30+
- fix(nextjs): Fix createRouteManifest with basePath ([#17838](https://github.com/getsentry/sentry-javascript/pull/17838))
31+
- fix(react): Add `POP` guard for long-running `pageload` spans ([#17867](https://github.com/getsentry/sentry-javascript/pull/17867))
32+
- fix(tracemetrics): Send boolean for internal replay attribute ([#17908](https://github.com/getsentry/sentry-javascript/pull/17908))
33+
- ref(core): Add weight tracking logic to browser logs/metrics ([#17901](https://github.com/getsentry/sentry-javascript/pull/17901))
34+
35+
<details>
36+
<summary> <strong>Internal Changes</strong> </summary>
37+
- chore(nextjs): Add Next.js 16 peer dependency ([#17925](https://github.com/getsentry/sentry-javascript/pull/17925))
38+
- chore(ci): Update Next.js canary testing ([#17939](https://github.com/getsentry/sentry-javascript/pull/17939))
39+
- chore: Bump size limit ([#17941](https://github.com/getsentry/sentry-javascript/pull/17941))
40+
- test(nextjs): Add next@16 e2e test ([#17922](https://github.com/getsentry/sentry-javascript/pull/17922))
41+
- test(nextjs): Update next 15 tests ([#17919](https://github.com/getsentry/sentry-javascript/pull/17919))
42+
- chore: Add external contributor to CHANGELOG.md ([#17915](https://github.com/getsentry/sentry-javascript/pull/17915))
43+
- chore: Add external contributor to CHANGELOG.md ([#17928](https://github.com/getsentry/sentry-javascript/pull/17928))
44+
- chore: Add external contributor to CHANGELOG.md ([#17940](https://github.com/getsentry/sentry-javascript/pull/17940))
45+
</details>
46+
47+
Work in this release was contributed by @seoyeon9888, @madhuchavva and @thedanchez. Thank you for your contributions!
848

949
## 10.19.0
1050

dev-packages/browser-integration-tests/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sentry-internal/browser-integration-tests",
3-
"version": "10.19.0",
3+
"version": "10.20.0",
44
"main": "index.js",
55
"license": "MIT",
66
"engines": {
@@ -43,7 +43,7 @@
4343
"@babel/preset-typescript": "^7.16.7",
4444
"@playwright/test": "~1.53.2",
4545
"@sentry-internal/rrweb": "2.34.0",
46-
"@sentry/browser": "10.19.0",
46+
"@sentry/browser": "10.20.0",
4747
"@supabase/supabase-js": "2.49.3",
4848
"axios": "^1.12.2",
4949
"babel-loader": "^8.2.2",
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { expect } from '@playwright/test';
2+
import { _INTERNAL_FLAG_BUFFER_SIZE as FLAG_BUFFER_SIZE } from '@sentry/core';
3+
import { sentryTest } from '../../../../../../utils/fixtures';
4+
import {
5+
envelopeRequestParser,
6+
shouldSkipFeatureFlagsTest,
7+
waitForErrorRequest,
8+
} from '../../../../../../utils/helpers';
9+
10+
sentryTest('GrowthBook onError: basic eviction/update and no async tasks', async ({ getLocalTestUrl, page }) => {
11+
if (shouldSkipFeatureFlagsTest()) {
12+
sentryTest.skip();
13+
}
14+
15+
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
16+
return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ id: 'test-id' }) });
17+
});
18+
19+
const url = await getLocalTestUrl({ testDir: __dirname, skipDsnRouteHandler: true });
20+
await page.goto(url);
21+
22+
await page.evaluate(bufferSize => {
23+
const gb = new (window as any).GrowthBook();
24+
25+
for (let i = 1; i <= bufferSize; i++) {
26+
gb.isOn(`feat${i}`);
27+
}
28+
29+
gb.__setOn(`feat${bufferSize + 1}`, true);
30+
gb.isOn(`feat${bufferSize + 1}`); // eviction
31+
32+
gb.__setOn('feat3', true);
33+
gb.isOn('feat3'); // update
34+
35+
// Test getFeatureValue with boolean values (should be captured)
36+
gb.__setFeatureValue('bool-feat', true);
37+
gb.getFeatureValue('bool-feat', false);
38+
39+
// Test getFeatureValue with non-boolean values (should be ignored)
40+
gb.__setFeatureValue('string-feat', 'hello');
41+
gb.getFeatureValue('string-feat', 'default');
42+
gb.__setFeatureValue('number-feat', 42);
43+
gb.getFeatureValue('number-feat', 0);
44+
}, FLAG_BUFFER_SIZE);
45+
46+
const reqPromise = waitForErrorRequest(page);
47+
await page.locator('#error').click();
48+
const req = await reqPromise;
49+
const event = envelopeRequestParser(req);
50+
51+
const values = event.contexts?.flags?.values || [];
52+
53+
// After the sequence of operations:
54+
// 1. feat1-feat100 are added (100 items)
55+
// 2. feat101 is added, evicts feat1 (100 items: feat2-feat100, feat101)
56+
// 3. feat3 is updated to true, moves to end (100 items: feat2, feat4-feat100, feat101, feat3)
57+
// 4. bool-feat is added, evicts feat2 (100 items: feat4-feat100, feat101, feat3, bool-feat)
58+
59+
const expectedFlags = [];
60+
for (let i = 4; i <= FLAG_BUFFER_SIZE; i++) {
61+
expectedFlags.push({ flag: `feat${i}`, result: false });
62+
}
63+
expectedFlags.push({ flag: `feat${FLAG_BUFFER_SIZE + 1}`, result: true });
64+
expectedFlags.push({ flag: 'feat3', result: true });
65+
expectedFlags.push({ flag: 'bool-feat', result: true }); // Only boolean getFeatureValue should be captured
66+
67+
expect(values).toEqual(expectedFlags);
68+
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
// Minimal mock GrowthBook class for tests
4+
window.GrowthBook = class {
5+
constructor() {
6+
this._onFlags = Object.create(null);
7+
this._featureValues = Object.create(null);
8+
}
9+
10+
isOn(featureKey) {
11+
return !!this._onFlags[featureKey];
12+
}
13+
14+
getFeatureValue(featureKey, defaultValue) {
15+
return Object.prototype.hasOwnProperty.call(this._featureValues, featureKey)
16+
? this._featureValues[featureKey]
17+
: defaultValue;
18+
}
19+
20+
// Helpers for tests
21+
__setOn(featureKey, value) {
22+
this._onFlags[featureKey] = !!value;
23+
}
24+
25+
__setFeatureValue(featureKey, value) {
26+
this._featureValues[featureKey] = value;
27+
}
28+
};
29+
30+
window.Sentry = Sentry;
31+
window.sentryGrowthBookIntegration = Sentry.growthbookIntegration({ growthbookClass: window.GrowthBook });
32+
33+
Sentry.init({
34+
dsn: 'https://public@dsn.ingest.sentry.io/1337',
35+
sampleRate: 1.0,
36+
integrations: [window.sentryGrowthBookIntegration],
37+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
document.getElementById('error').addEventListener('click', () => {
2+
throw new Error('Button triggered error');
3+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<button id="error">Throw Error</button>
8+
</body>
9+
<script src="./subject.js"></script>
10+
</html>
11+
12+
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { expect } from '@playwright/test';
2+
import type { Scope } from '@sentry/browser';
3+
import { sentryTest } from '../../../../../../utils/fixtures';
4+
import {
5+
envelopeRequestParser,
6+
shouldSkipFeatureFlagsTest,
7+
waitForErrorRequest,
8+
} from '../../../../../../utils/helpers';
9+
10+
sentryTest('GrowthBook onError: forked scopes are isolated', async ({ getLocalTestUrl, page }) => {
11+
if (shouldSkipFeatureFlagsTest()) {
12+
sentryTest.skip();
13+
}
14+
15+
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
16+
return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ id: 'test-id' }) });
17+
});
18+
19+
const url = await getLocalTestUrl({ testDir: __dirname, skipDsnRouteHandler: true });
20+
await page.goto(url);
21+
22+
const forkedReqPromise = waitForErrorRequest(page, event => !!event.tags?.isForked === true);
23+
const mainReqPromise = waitForErrorRequest(page, event => !!event.tags?.isForked === false);
24+
25+
await page.evaluate(() => {
26+
const Sentry = (window as any).Sentry;
27+
const errorButton = document.querySelector('#error') as HTMLButtonElement;
28+
const gb = new (window as any).GrowthBook();
29+
30+
gb.__setOn('shared', true);
31+
gb.__setOn('main', true);
32+
33+
gb.isOn('shared');
34+
35+
Sentry.withScope((scope: Scope) => {
36+
gb.__setOn('forked', true);
37+
gb.__setOn('shared', false);
38+
gb.isOn('forked');
39+
gb.isOn('shared');
40+
scope.setTag('isForked', true);
41+
errorButton.click();
42+
});
43+
44+
gb.isOn('main');
45+
Sentry.getCurrentScope().setTag('isForked', false);
46+
errorButton.click();
47+
return true;
48+
});
49+
50+
const forkedReq = await forkedReqPromise;
51+
const forkedEvent = envelopeRequestParser(forkedReq);
52+
53+
const mainReq = await mainReqPromise;
54+
const mainEvent = envelopeRequestParser(mainReq);
55+
56+
expect(forkedEvent.contexts?.flags?.values).toEqual([
57+
{ flag: 'forked', result: true },
58+
{ flag: 'shared', result: false },
59+
]);
60+
61+
expect(mainEvent.contexts?.flags?.values).toEqual([
62+
{ flag: 'shared', result: true },
63+
{ flag: 'main', result: true },
64+
]);
65+
});

0 commit comments

Comments
 (0)