Skip to content

Commit 563d2fc

Browse files
authored
Merge branch 'develop' into feat/legacy-bundler-plugin-packages
2 parents d1a1537 + 40ad4ca commit 563d2fc

104 files changed

Lines changed: 2505 additions & 692 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/dependency-review-config.yml‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,17 @@ allow-ghsas:
3030
# 0.35.0, which is outside that range. Already present on develop via sharp 0.32.6
3131
# and 0.34.5, both of which are affected by the same advisory.
3232
- GHSA-f88m-g3jw-g9cj
33+
# axios, pinned exactly to 1.18.1 by nx (dev-only build tooling, not shipped).
34+
# Can be removed once nx pins axios >= 1.20.0.
35+
- GHSA-542g-h47m-68v8
36+
- GHSA-3pq3-5fj3-cg6v
37+
- GHSA-x97p-jq2g-jp4f
38+
- GHSA-mghh-pgcx-3jjj
39+
- GHSA-c29m-xwm3-cm6r
40+
- GHSA-r4gj-5m52-g5wh
41+
- GHSA-m8m8-qj5v-23w3
42+
# brace-expansion, pinned exactly to 5.0.8 by nx (dev-only build tooling, not shipped).
43+
# Can be removed once nx pins brace-expansion >= 5.0.11.
44+
- GHSA-rgw5-rvv9-x895
45+
- GHSA-6j4f-fj2g-mc7p
46+
- GHSA-qhr7-859c-m2p7

‎CHANGELOG.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
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 @minwookshin. Thank you for your contribution!
8+
79
## 11.4.0
810

911
- feat(sveltekit): Support stable SvelteKit 3 ([#25009](https://github.com/getsentry/sentry-javascript/pull/25009))
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { sendPortToRunner } from '@sentry-internal/node-integration-tests';
2+
import * as Sentry from '@sentry/bun';
3+
4+
Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 1 });
5+
6+
const server = Bun.serve({
7+
port: 0,
8+
fetch(request) {
9+
const path = new URL(request.url).pathname;
10+
if (path === '/error') {
11+
throw new Error('handler failed');
12+
}
13+
const span = Sentry.getActiveSpan();
14+
const body = new ReadableStream({
15+
async start(controller) {
16+
controller.enqueue(new TextEncoder().encode('data: first\n\n'));
17+
await Bun.sleep(50);
18+
if (path === '/stream-error') {
19+
controller.error(new Error('stream failed'));
20+
return;
21+
}
22+
controller.enqueue(new TextEncoder().encode(`data: recording=${span?.isRecording()}\n\n`));
23+
span?.setAttribute('test.stream.completed', true);
24+
controller.close();
25+
},
26+
});
27+
return new Response(body, { status: 201, headers: { 'content-type': 'text/event-stream' } });
28+
},
29+
error() {
30+
return new Response('failed', { status: 500 });
31+
},
32+
});
33+
sendPortToRunner(server.port!);
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { afterAll, expect, test } from 'vitest';
2+
import { cleanupChildProcesses, createRunner } from '../../../node-integration-tests/utils/runner';
3+
4+
afterAll(cleanupChildProcesses);
5+
6+
test('records streaming work after the response headers have been returned', async () => {
7+
const runner = createRunner(__dirname, 'index.ts')
8+
.withMockSentryServer()
9+
.unordered()
10+
.expect({
11+
span: container => {
12+
const root = container.items.find(item => item.is_segment);
13+
expect(root).toEqual(
14+
expect.objectContaining({
15+
attributes: expect.objectContaining({
16+
'url.path': { value: '/events', type: 'string' },
17+
'http.response.status_code': { value: 201, type: 'integer' },
18+
'test.stream.completed': { value: true, type: 'boolean' },
19+
}),
20+
}),
21+
);
22+
},
23+
})
24+
.start();
25+
expect(await runner.makeRequest('get', '/events')).toBe('data: first\n\ndata: recording=true\n\n');
26+
await runner.completed();
27+
});
28+
29+
test('records a thrown handler as an error span', async () => {
30+
const runner = createRunner(__dirname, 'index.ts')
31+
.withMockSentryServer()
32+
.unordered()
33+
.expect({
34+
span: container => {
35+
const root = container.items.find(item => item.is_segment);
36+
expect(root).toEqual(expect.objectContaining({ status: 'error' }));
37+
},
38+
})
39+
.start();
40+
await runner.makeRequest('get', '/error', { expectError: true });
41+
await runner.completed();
42+
});
43+
44+
test('captures a response stream failure with its request context and error span', async () => {
45+
let spanTraceId: string | undefined;
46+
let eventTraceId: string | undefined;
47+
const runner = createRunner(__dirname, 'index.ts')
48+
.withMockSentryServer()
49+
.unordered()
50+
.expect({
51+
span: container => {
52+
const roots = container.items.filter(item => item.is_segment);
53+
expect(roots).toHaveLength(1);
54+
const root = roots[0]!;
55+
expect(root.status).toBe('error');
56+
expect(root.attributes['url.path']?.value).toBe('/stream-error');
57+
expect(root.attributes['http.response.status_code']?.value).toBe(201);
58+
spanTraceId = root.trace_id;
59+
},
60+
})
61+
.expect({
62+
event: event => {
63+
expect(event.exception?.values).toHaveLength(1);
64+
const exception = event.exception!.values![0]!;
65+
expect(exception.type).toBe('Error');
66+
expect(exception.value).toBe('stream failed');
67+
expect(exception.mechanism).toEqual({ type: 'auto.http.bun.serve', handled: false });
68+
expect(event.request?.method).toBe('GET');
69+
expect(new URL(event.request!.url!).pathname).toBe('/stream-error');
70+
eventTraceId = event.contexts?.trace?.trace_id;
71+
},
72+
})
73+
.start();
74+
75+
await expect.poll(() => runner.getPort(), { timeout: 30_000 }).toBeTypeOf('number');
76+
const response = await fetch(`http://localhost:${runner.getPort()}/stream-error`);
77+
expect(response.status).toBe(201);
78+
// Bun versions differ in whether a failed stream rejects or closes the HTTP response body.
79+
await Promise.allSettled([response.text()]);
80+
await runner.completed();
81+
expect(spanTraceId).toMatch(/^[a-f\d]{32}$/);
82+
expect(eventTraceId).toBe(spanTraceId);
83+
});

‎dev-packages/e2e-tests/README.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ Apps like `cloudflare-workers-send-to-sentry` deploy the built app as a real Wor
139139
## Runtime variants (Bun, Deno, Cloudflare)
140140

141141
To test a framework on a runtime other than Node.js, add an `optionalVariants` entry to the existing test app instead of
142-
creating a new app. `react-router-8-framework` is the reference setup.
142+
creating a new app. When the variant is green, move it to `variants`, so that it is required. `react-router-8-framework`
143+
is the reference setup.
143144

144145
- **`runtime`**: set `"runtime": "bun"`, `"deno"` or `"cloudflare"` on the variant. For such a variant, CI installs Bun
145146
or Deno, and the runner and CI set the `RUNTIME` env var for the build and the assert command. Without `runtime`,

‎dev-packages/e2e-tests/test-applications/browser-webworker-vite/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
},
2020
"dependencies": {
2121
"@sentry/browser": "file:../../packed/sentry-browser-packed.tgz",
22-
"@sentry/vite-plugin": "^5.3.0"
22+
"@sentry/vite-plugin": "^5.4.1"
2323
},
2424
"volta": {
2525
"node": "20.19.2",

‎dev-packages/e2e-tests/test-applications/debug-id-sourcemaps/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"devDependencies": {
1616
"rollup": "^4.35.0",
1717
"vitest": "^4.1.11",
18-
"@sentry/rollup-plugin": "^5.3.0"
18+
"@sentry/rollup-plugin": "^5.4.1"
1919
},
2020
"volta": {
2121
"extends": "../../package.json"

‎dev-packages/e2e-tests/test-applications/hydrogen-react-router-7/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"dependencies": {
1717
"@sentry/cloudflare": "file:../../packed/sentry-cloudflare-packed.tgz",
1818
"@sentry/react-router": "file:../../packed/sentry-react-router-packed.tgz",
19-
"@sentry/vite-plugin": "^5.3.0",
19+
"@sentry/vite-plugin": "^5.4.1",
2020
"@shopify/hydrogen": "2025.5.0",
2121
"@shopify/remix-oxygen": "^3.0.0",
2222
"graphql": "^16.10.0",

‎dev-packages/e2e-tests/test-applications/react-router-8-framework/app/entry.server.cloudflare.tsx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,5 @@ export const handleError: HandleErrorFunction = (error, { request }) => {
4848
};
4949

5050
export default Sentry.wrapSentryHandleRequest(handleRequest);
51+
52+
export const instrumentations = [Sentry.createSentryServerInstrumentation()];

‎dev-packages/e2e-tests/test-applications/react-router-8-framework/app/entry.server.tsx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@ const handleRequest = Sentry.createSentryHandleRequest({
1818
export default handleRequest;
1919

2020
export const handleError: HandleErrorFunction = Sentry.createSentryHandleError({ logErrors: true });
21+
22+
export const instrumentations = [Sentry.createSentryServerInstrumentation()];

0 commit comments

Comments
 (0)