Skip to content

Commit 219bc48

Browse files
committed
Merge remote-tracking branch 'origin/develop' into pr-24768
# Conflicts: # packages/bundler-plugins/package.json # yarn.lock
2 parents d6ab260 + 68b6f79 commit 219bc48

283 files changed

Lines changed: 4161 additions & 4708 deletions

File tree

Some content is hidden

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

‎.github/workflows/cleanup-e2e-workers.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
1717
strategy:
1818
matrix:
19-
# Name prefix of every E2E app that deploys a real worker, see the app's global-setup.mjs
19+
# Name prefix of every E2E app that deploys a real worker, see the app's global-setup.ts
2020
worker-prefix:
2121
- e2e-send-to-sentry
2222
steps:

‎.size-limit.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ module.exports = [
406406
import: createImport('init'),
407407
ignore: [...builtinModules, ...nodePrefixedBuiltinModules],
408408
gzip: true,
409-
limit: '142 KB',
409+
limit: '143 KB',
410410
disablePlugins: ['@size-limit/esbuild'],
411411
},
412412
{

‎CHANGELOG.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
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 @nabi-noor and @LuccaRebelloToledo. Thank you for your contributions!
7+
Work in this release was contributed by @nabi-noor, @LuccaRebelloToledo, and @andasan. Thank you for your contributions!
88

99
## 11.1.0
1010

‎dev-packages/browser-integration-tests/suites/replay/largeMutations/mutationLimit/test.ts‎

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { expect } from '@playwright/test';
2+
import { EventType } from '@sentry/rrweb';
23
import { sentryTest } from '../../../../utils/fixtures';
34
import {
5+
collectReplayRequests,
6+
getReplayBreadcrumbs,
47
getReplayRecordingContent,
58
getReplaySnapshot,
69
shouldSkipReplayTest,
@@ -25,14 +28,20 @@ sentryTest(
2528
const [res0] = await Promise.all([waitForReplayRequest(page, 0), gotoPageAndClick()]);
2629
await forceFlushReplay();
2730

28-
const [res1] = await Promise.all([
29-
waitForReplayRequest(page, (_event, res) => {
30-
const parsed = getReplayRecordingContent(res);
31-
return !!parsed.incrementalSnapshots.length || !!parsed.fullSnapshots.length;
32-
}),
33-
page.locator('#button-add').click(),
34-
forceFlushReplay(),
35-
]);
31+
// The `replay.mutations` breadcrumb is added asynchronously (once rrweb's
32+
// MutationObserver fires) and can land in a different flush than the
33+
// incremental snapshots and the `ui.click` breadcrumb. Collect across
34+
// requests until the mutation breadcrumb has arrived rather than betting on
35+
// a single request containing everything.
36+
const requestsPromise = collectReplayRequests(
37+
page,
38+
recordingSnapshots => getReplayBreadcrumbs(recordingSnapshots, 'replay.mutations').length > 0,
39+
);
40+
41+
await page.locator('#button-add').click();
42+
await forceFlushReplay();
43+
44+
const { replayRecordingSnapshots } = await requestsPromise;
3645

3746
// replay should be stopped due to mutation limit
3847
let replay = await getReplaySnapshot(page);
@@ -48,11 +57,21 @@ sentryTest(
4857
const replayData0 = getReplayRecordingContent(res0);
4958
expect(replayData0.fullSnapshots.length).toBe(1);
5059

60+
const fullSnapshots = replayRecordingSnapshots.filter(snapshot => snapshot.type === EventType.FullSnapshot);
61+
const incrementalSnapshots = replayRecordingSnapshots.filter(
62+
snapshot => snapshot.type === EventType.IncrementalSnapshot,
63+
);
64+
// A still-in-flight envelope from the setup flush can re-deliver the
65+
// `#noop` `ui.click` breadcrumb into the collected set, so assert on the
66+
// unique categories rather than the raw (potentially duplicated) list.
67+
const breadcrumbCategories = [
68+
...new Set(getReplayBreadcrumbs(replayRecordingSnapshots).map(({ category }) => category)),
69+
].sort();
70+
5171
// Breadcrumbs (click and mutation);
52-
const replayData1 = getReplayRecordingContent(res1);
53-
expect(replayData1.fullSnapshots.length).toBe(0);
54-
expect(replayData1.incrementalSnapshots.length).toBeGreaterThan(0);
55-
expect(replayData1.breadcrumbs.map(({ category }) => category).sort()).toEqual(['replay.mutations', 'ui.click']);
72+
expect(fullSnapshots.length).toBe(0);
73+
expect(incrementalSnapshots.length).toBeGreaterThan(0);
74+
expect(breadcrumbCategories).toEqual(['replay.mutations', 'ui.click']);
5675

5776
replay = await getReplaySnapshot(page);
5877
expect(replay.session).toBe(undefined);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Bundles one Node suite scenario with `@sentry/bun/plugin`, so the plugin can inject the
2+
// diagnostics channels into the libraries the scenario uses. The runner calls this script with the
3+
// scenario path when `RUNTIME_BUILD_SCRIPT` points to it, and runs the printed output file instead.
4+
import { sentryBunPlugin } from '@sentry/bun/plugin';
5+
import { dirname, join, relative } from 'node:path';
6+
7+
const NODE_SUITES_ROOT = join(import.meta.dir, '..', '..', 'node-integration-tests');
8+
const BUILD_ROOT = join(import.meta.dir, '..', 'build');
9+
10+
const entry = process.argv[2];
11+
if (!entry) {
12+
// eslint-disable-next-line no-console
13+
console.error('BUILD_FAILED no scenario path');
14+
process.exit(1);
15+
}
16+
17+
const result = await Bun.build({
18+
entrypoints: [entry],
19+
target: 'bun',
20+
// Mirrors the scenario's folder, so relative paths between scenarios keep their shape.
21+
outdir: join(BUILD_ROOT, relative(NODE_SUITES_ROOT, dirname(entry))),
22+
sourcemap: 'linked',
23+
// The instrument file is preloaded unbundled, so the bundle must share its `@sentry/*` packages.
24+
// knex requires the drivers of all its dialects, and the ones that are not installed must stay
25+
// external so the bundle still builds.
26+
external: ['@sentry/*', '@sentry-internal/*', 'better-sqlite3', 'oracledb', 'pg-query-stream', 'sqlite3'],
27+
plugins: [sentryBunPlugin()],
28+
});
29+
30+
const output = result.outputs.find(file => file.kind === 'entry-point');
31+
if (!result.success || !output) {
32+
// eslint-disable-next-line no-console
33+
console.error('BUILD_FAILED', result.logs);
34+
process.exit(1);
35+
}
36+
37+
// eslint-disable-next-line no-console
38+
console.log(`BUILD_OK ${output.path}`);

‎dev-packages/bun-integration-tests/node-suites/excludes.ts‎

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ const NO_OUTGOING_HTTP_INSTRUMENTATION = [
7575
// `bun run` cannot inject the diagnostics channels into libraries, so framework, database and AI
7676
// instrumentation creates no spans. Apps must be built with `@sentry/bun/plugin`.
7777
// See https://github.com/getsentry/sentry-javascript/issues/23882
78-
const NO_AUTO_INSTRUMENTATION = [
78+
export const NO_AUTO_INSTRUMENTATION = [
7979
'suites/express/**',
8080
'suites/fs-instrumentation/test.ts',
8181
'suites/hono-sdk/test.ts',
@@ -216,3 +216,56 @@ export const SENTRY_BUN_EXCLUDE = [
216216
...NO_NATIVE_NODE_FETCH_INTEGRATION,
217217
...FETCH_INTEGRATION_DIFFERS,
218218
];
219+
220+
// The build project (`node-suites-bun-build`) runs the suites of `NO_AUTO_INSTRUMENTATION` with the
221+
// scenarios bundled by `@sentry/bun/plugin`. These do not run there.
222+
223+
// On Bun the channel integrations subscribe at `init()` by design, and this suite checks that
224+
// they wait until their module loads.
225+
const BUN_BUILD_EAGER_SUBSCRIPTION = ['suites/tracing/orchestrion-lazy-registration/test.ts'];
226+
227+
// The first `init()` has no DSN, so `bunHttpServerIntegration` is not set up, and the suite then
228+
// adds only `httpIntegration`. On Bun that does not isolate requests, because Bun does not publish
229+
// `http.server.request.start`.
230+
const BUN_BUILD_NO_HTTP_SERVER_INTEGRATION = ['suites/express/multiple-init/test.ts'];
231+
232+
// Some or all tests fail with the bundled scenarios, cause not investigated yet. In
233+
// `express/tracing` only the request data tests fail: they set `httpIntegration` options, and with
234+
// `@sentry/bun` the request body comes from `bunHttpServerIntegration`.
235+
const BUN_BUILD_NOT_TRIAGED = [
236+
'suites/express/sentry-trace/test.ts',
237+
'suites/express/tracing/test.ts',
238+
'suites/express/with-http/**',
239+
'suites/hono-sdk/test.ts',
240+
'suites/pino/test.ts',
241+
'suites/tracing/google-genai-v2/test.ts',
242+
'suites/tracing/google-genai/test.ts',
243+
'suites/tracing/langchain/v1/test.ts',
244+
'suites/tracing/mastra/test.ts',
245+
'suites/tracing/mcp-handler-exact-once/test.ts',
246+
'suites/tracing/mcp-server-streamed/test.ts',
247+
'suites/tracing/mongodb-v4/test.ts',
248+
'suites/tracing/mongodb-v5/test.ts',
249+
'suites/tracing/mongodb-v6/test.ts',
250+
'suites/tracing/mongodb-v7/test.ts',
251+
'suites/tracing/mongodb/test.ts',
252+
'suites/tracing/mongoose-tracing-channel/test.ts',
253+
'suites/tracing/mongoose-v5/test.ts',
254+
'suites/tracing/mongoose-v7/test.ts',
255+
'suites/tracing/mongoose-v8/test.ts',
256+
'suites/tracing/mongoose-v9/test.ts',
257+
'suites/tracing/mongoose/test.ts',
258+
'suites/tracing/mysql/test.ts',
259+
'suites/tracing/openai/test.ts',
260+
'suites/tracing/prisma-orm-v8/test.ts',
261+
'suites/tracing/together-ai/test.ts',
262+
'suites/tracing/vercelai/test.ts',
263+
'suites/tracing/vercelai/v6_v7/test.ts',
264+
];
265+
266+
export const BUN_BUILD_EXCLUDE = [
267+
'**/node_modules/**',
268+
...BUN_BUILD_EAGER_SUBSCRIPTION,
269+
...BUN_BUILD_NO_HTTP_SERVER_INTEGRATION,
270+
...BUN_BUILD_NOT_TRIAGED,
271+
];

‎dev-packages/bun-integration-tests/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"@sentry-internal/node-integration-tests": "11.1.0",
2525
"@sentry-internal/test-utils": "11.1.0",
2626
"bun-types": "^1.2.9",
27-
"vitest": "^3.2.7"
27+
"vitest": "^4.1.11"
2828
},
2929
"volta": {
3030
"extends": "../../package.json"

‎dev-packages/bun-integration-tests/tsconfig.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"include": ["suites/**/*.ts", "node-suites/**/*.ts", "*.ts"],
55

66
"compilerOptions": {
7-
"lib": ["ES2020"],
7+
"lib": ["DOM", "ES2020"],
88
"esModuleInterop": true,
99
"types": ["bun-types"]
1010
}

‎dev-packages/bun-integration-tests/vite.config.mts‎

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import { fileURLToPath } from 'node:url';
22
import { defineConfig } from 'vitest/config';
33
import baseConfig from '../../vite/vite.config';
4-
import { NODE_SUITES_EXCLUDE, SENTRY_BUN_EXCLUDE, SENTRY_NODE_EXCLUDE } from './node-suites/excludes';
4+
import {
5+
BUN_BUILD_EXCLUDE,
6+
NO_AUTO_INSTRUMENTATION,
7+
NODE_SUITES_EXCLUDE,
8+
SENTRY_BUN_EXCLUDE,
9+
SENTRY_NODE_EXCLUDE,
10+
} from './node-suites/excludes';
511

612
const NODE_SUITES_ROOT = fileURLToPath(new URL('../node-integration-tests', import.meta.url));
713

@@ -46,11 +52,9 @@ export default defineConfig({
4652
env: { RUNTIME: 'bun' },
4753
// Above the 30 second port timeout of the runner on Bun, so a slow start can still pass.
4854
testTimeout: 45_000,
49-
poolOptions: {
50-
threads: {
51-
singleThread: true,
52-
},
53-
},
55+
maxWorkers: 1,
56+
// Vitest requires projects with a different `maxWorkers` to run in their own group.
57+
sequence: { groupOrder: 1 },
5458
},
5559
},
5660
{
@@ -82,6 +86,24 @@ export default defineConfig({
8286
},
8387
},
8488
},
89+
{
90+
extends: true,
91+
test: {
92+
...nodeSuitesTest,
93+
// The auto-instrumentation suites, with each scenario bundled by `@sentry/bun/plugin` before
94+
// it starts, as Bun apps must be built to get these spans.
95+
// See https://github.com/getsentry/sentry-javascript/issues/23882
96+
name: 'node-suites-bun-build',
97+
include: NO_AUTO_INSTRUMENTATION.map(glob => (glob.endsWith('/**') ? `${glob}/test.ts` : glob)),
98+
exclude: BUN_BUILD_EXCLUDE,
99+
env: {
100+
RUNTIME: 'bun',
101+
RUNTIME_PRELOAD: fileURLToPath(new URL('./node-suites/alias-sentry-bun.ts', import.meta.url)),
102+
RUNTIME_BUILD_SCRIPT: fileURLToPath(new URL('./node-suites/bun-build.ts', import.meta.url)),
103+
EXPECTED_SDK_NAME: 'sentry.javascript.bun',
104+
},
105+
},
106+
},
85107
],
86108
},
87109
});

‎dev-packages/bundler-plugin-integration-tests/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"devDependencies": {
1818
"premove": "^4.0.0",
1919
"typescript": "~6.0.3",
20-
"vitest": "^3.2.7"
20+
"vitest": "^4.1.11"
2121
},
2222
"volta": {
2323
"extends": "../../package.json"

0 commit comments

Comments
 (0)