Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 70811c9

Browse files
authored
Merge pull request #17807 from getsentry/prepare-release/10.16.0
meta(changelog): Update changelog for 10.16.0
2 parents 863c169 + 55d8514 commit 70811c9

File tree

38 files changed

+1716
-210
lines changed

38 files changed

+1716
-210
lines changed

‎.cursor/commands/publish_release.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Release Command
2+
3+
Execute the standard Sentry JavaScript SDK release process.
4+
5+
Find the "publishing_release" rule in `.cursor/rules/publishing_release` and follow those complete instructions step by step.

‎CHANGELOG.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,31 @@
44

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

7+
## 10.16.0
8+
9+
- feat(logs): Add internal `replay_is_buffering` flag ([#17752](https://github.com/getsentry/sentry-javascript/pull/17752))
10+
- feat(react-router): Update loadContext type to be compatible with middleware ([#17758](https://github.com/getsentry/sentry-javascript/pull/17758))
11+
- feat(replay/logs): Only attach sampled replay Ids to logs ([#17750](https://github.com/getsentry/sentry-javascript/pull/17750))
12+
- fix(browser): Use current start timestamp for CLS span when CLS is 0 ([#17800](https://github.com/getsentry/sentry-javascript/pull/17800))
13+
- fix(core): Prevent `instrumentAnthropicAiClient` breaking MessageStream api ([#17754](https://github.com/getsentry/sentry-javascript/pull/17754))
14+
- fix(nextjs): Don't use chalk in turbopack config file ([#17806](https://github.com/getsentry/sentry-javascript/pull/17806))
15+
- fix(react): Do not send additional navigation span on pageload ([#17799](https://github.com/getsentry/sentry-javascript/pull/17799))
16+
17+
<details>
18+
<summary> <strong>Internal Changes</strong> </summary>
19+
20+
- build(aws): Ensure AWS build cache does not keep old files ([#17776](https://github.com/getsentry/sentry-javascript/pull/17776))
21+
- chore: Add `publish_release` command ([#17797](https://github.com/getsentry/sentry-javascript/pull/17797))
22+
- ref(aws-serverless): Add resolution for `import-in-the-middle` when building the Lambda layer ([#17780](https://github.com/getsentry/sentry-javascript/pull/17780))
23+
- ref(aws-serverless): Improve README with better examples ([#17787](https://github.com/getsentry/sentry-javascript/pull/17787))
24+
- ref(core): Improve promise buffer ([#17788](https://github.com/getsentry/sentry-javascript/pull/17788))
25+
- Revert "test(e2e): Pin `import-in-the-middle@1.14.2` due to `@vercel/nft` incompatibility ([#17777](https://github.com/getsentry/sentry-javascript/pull/17777))" (#17784)
26+
- test(e2e): Pin `import-in-the-middle@1.14.2` due to `@vercel/nft` incompatibility ([#17777](https://github.com/getsentry/sentry-javascript/pull/17777))
27+
- test(nextjs): Add route handler tests for turbopack ([#17515](https://github.com/getsentry/sentry-javascript/pull/17515))
28+
- test(react-router): Test v8 middleware ([#17783](https://github.com/getsentry/sentry-javascript/pull/17783))
29+
30+
</details>
31+
732
## 10.15.0
833

934
### Important Changes
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export async function GET(request: Request) {
2+
throw new Error('Dynamic route handler error');
3+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { NextResponse } from 'next/server';
2+
3+
export async function GET() {
4+
return NextResponse.json({ name: 'Beep' });
5+
}
6+
7+
export async function POST() {
8+
return NextResponse.json({ name: 'Boop' }, { status: 400 });
9+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { NextResponse } from 'next/server';
2+
3+
export async function GET(request: Request) {
4+
return NextResponse.json({ name: 'Static' });
5+
}

‎dev-packages/e2e-tests/test-applications/nextjs-turbo/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"@types/node": "^18.19.1",
1818
"@types/react": "^19",
1919
"@types/react-dom": "^19",
20-
"next": "^15.3.5",
20+
"next": "^15.5.4",
2121
"react": "^19",
2222
"react-dom": "^19",
2323
"typescript": "~5.0.0"
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { expect, test } from '@playwright/test';
2+
import { waitForError, waitForTransaction } from '@sentry-internal/test-utils';
3+
4+
test('Should create a transaction for dynamic route handlers', async ({ request }) => {
5+
const routehandlerTransactionPromise = waitForTransaction('nextjs-turbo', async transactionEvent => {
6+
return transactionEvent?.transaction === 'GET /route-handlers/[param]';
7+
});
8+
9+
const response = await request.get('/route-handlers/foo');
10+
expect(await response.json()).toStrictEqual({ name: 'Beep' });
11+
12+
const routehandlerTransaction = await routehandlerTransactionPromise;
13+
14+
expect(routehandlerTransaction.contexts?.trace?.status).toBe('ok');
15+
expect(routehandlerTransaction.contexts?.trace?.op).toBe('http.server');
16+
});
17+
18+
test('Should create a transaction for static route handlers', async ({ request }) => {
19+
const routehandlerTransactionPromise = waitForTransaction('nextjs-turbo', async transactionEvent => {
20+
return transactionEvent?.transaction === 'GET /route-handlers/static';
21+
});
22+
23+
const response = await request.get('/route-handlers/static');
24+
expect(await response.json()).toStrictEqual({ name: 'Static' });
25+
26+
const routehandlerTransaction = await routehandlerTransactionPromise;
27+
28+
expect(routehandlerTransaction.contexts?.trace?.status).toBe('ok');
29+
expect(routehandlerTransaction.contexts?.trace?.op).toBe('http.server');
30+
});
31+
32+
test('Should create a transaction for route handlers and correctly set span status depending on http status', async ({
33+
request,
34+
}) => {
35+
const routehandlerTransactionPromise = waitForTransaction('nextjs-turbo', async transactionEvent => {
36+
return transactionEvent?.transaction === 'POST /route-handlers/[param]';
37+
});
38+
39+
const response = await request.post('/route-handlers/bar');
40+
expect(await response.json()).toStrictEqual({ name: 'Boop' });
41+
42+
const routehandlerTransaction = await routehandlerTransactionPromise;
43+
44+
expect(routehandlerTransaction.contexts?.trace?.status).toBe('invalid_argument');
45+
expect(routehandlerTransaction.contexts?.trace?.op).toBe('http.server');
46+
});
47+
48+
test('Should record exceptions and transactions for faulty route handlers', async ({ request }) => {
49+
const errorEventPromise = waitForError('nextjs-turbo', errorEvent => {
50+
return errorEvent?.exception?.values?.[0]?.value === 'Dynamic route handler error';
51+
});
52+
53+
const routehandlerTransactionPromise = waitForTransaction('nextjs-turbo', async transactionEvent => {
54+
return transactionEvent?.transaction === 'GET /route-handlers/[param]/error';
55+
});
56+
57+
await request.get('/route-handlers/boop/error').catch(() => {});
58+
59+
const routehandlerTransaction = await routehandlerTransactionPromise;
60+
const routehandlerError = await errorEventPromise;
61+
62+
expect(routehandlerTransaction.contexts?.trace?.status).toBe('internal_error');
63+
expect(routehandlerTransaction.contexts?.trace?.op).toBe('http.server');
64+
expect(routehandlerTransaction.contexts?.trace?.origin).toContain('auto');
65+
66+
expect(routehandlerError.exception?.values?.[0].value).toBe('Dynamic route handler error');
67+
68+
expect(routehandlerError.request?.method).toBe('GET');
69+
// todo: make sure url is attached to request object
70+
// expect(routehandlerError.request?.url).toContain('/route-handlers/boop/error');
71+
72+
expect(routehandlerError.transaction).toBe('/route-handlers/[param]/error');
73+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { createContext } from 'react-router';
2+
3+
export type User = {
4+
id: string;
5+
name: string;
6+
};
7+
8+
export const userContext = createContext<User | null>(null);

‎dev-packages/e2e-tests/test-applications/react-router-7-framework/app/routes.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ export default [
1717
route('static', 'routes/performance/static.tsx'),
1818
route('server-loader', 'routes/performance/server-loader.tsx'),
1919
route('server-action', 'routes/performance/server-action.tsx'),
20+
route('with-middleware', 'routes/performance/with-middleware.tsx'),
2021
]),
2122
] satisfies RouteConfig;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import type { Route } from './+types/with-middleware';
2+
import type { User } from '../../context';
3+
import { userContext } from '../../context';
4+
import * as Sentry from '@sentry/react-router';
5+
6+
async function getUser() {
7+
await new Promise(resolve => setTimeout(resolve, 500));
8+
return {
9+
id: '1',
10+
name: 'Carlos Gomez',
11+
};
12+
}
13+
14+
const authMiddleware: Route.MiddlewareFunction = async ({ request, context }, next) => {
15+
Sentry.startSpan({ name: 'authMiddleware', op: 'middleware.auth' }, async () => {
16+
const user: User = await getUser();
17+
context.set(userContext, user);
18+
await next();
19+
});
20+
};
21+
22+
export const middleware: Route.MiddlewareFunction[] = [authMiddleware];
23+
24+
export const loader = async ({ context }: Route.LoaderArgs) => {
25+
const user = context.get(userContext);
26+
return { user };
27+
};
28+
29+
export default function WithMiddlewarePage({ loaderData }: Route.ComponentProps) {
30+
const { user } = loaderData;
31+
32+
return (
33+
<div>
34+
<h1>With Middleware Page</h1>
35+
<p>User: {user?.name}</p>
36+
</div>
37+
);
38+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /