Skip to content

Commit be665a3

Browse files
committed
add route handler tests
1 parent 1a3f402 commit be665a3

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { NextResponse } from 'next/server';
2+
3+
export const runtime = 'edge';
4+
export const dynamic = 'force-dynamic';
5+
6+
export async function GET() {
7+
return NextResponse.json({ message: 'Hello Edge Route Handler' });
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { NextResponse } from 'next/server';
2+
3+
export const dynamic = 'force-dynamic';
4+
5+
export async function GET() {
6+
return NextResponse.json({ message: 'Hello Node Route Handler' });
7+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import test, { expect } from '@playwright/test';
2+
import { waitForTransaction } from '@sentry-internal/test-utils';
3+
4+
test('Should create a transaction for node route handlers', async ({ request }) => {
5+
const routehandlerTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => {
6+
console.log(transactionEvent?.transaction);
7+
return transactionEvent?.transaction === 'GET /route-handler/[xoxo]/node';
8+
});
9+
10+
const response = await request.get('/route-handler/123/node', { headers: { 'x-charly': 'gomez' } });
11+
expect(await response.json()).toStrictEqual({ message: 'Hello Node Route Handler' });
12+
13+
const routehandlerTransaction = await routehandlerTransactionPromise;
14+
15+
expect(routehandlerTransaction.contexts?.trace?.status).toBe('ok');
16+
expect(routehandlerTransaction.contexts?.trace?.op).toBe('http.server');
17+
18+
// This is flaking on dev mode
19+
if (process.env.TEST_ENV !== 'development' && process.env.TEST_ENV !== 'dev-turbopack') {
20+
expect(routehandlerTransaction.contexts?.trace?.data?.['http.request.header.x_charly']).toBe('gomez');
21+
}
22+
});
23+
24+
test('Should create a transaction for edge route handlers', async ({ request }) => {
25+
const routehandlerTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => {
26+
return transactionEvent?.transaction === 'GET /route-handler/[xoxo]/edge';
27+
});
28+
29+
const response = await request.get('/route-handler/123/edge', { headers: { 'x-charly': 'gomez' } });
30+
expect(await response.json()).toStrictEqual({ message: 'Hello Edge Route Handler' });
31+
32+
const routehandlerTransaction = await routehandlerTransactionPromise;
33+
34+
expect(routehandlerTransaction.contexts?.trace?.status).toBe('ok');
35+
expect(routehandlerTransaction.contexts?.trace?.op).toBe('http.server');
36+
// todo: check if we can set request headers for edge on sdkProcessingMetadata
37+
// expect(routehandlerTransaction.contexts?.trace?.data?.['http.request.header.x-charly']).toBe('gomez');
38+
});

packages/nextjs/src/server/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export function init(options: NodeOptions): NodeClient | undefined {
165165
client?.on('spanStart', span => {
166166
const spanAttributes = spanToJSON(span).data;
167167
const rootSpan = getRootSpan(span);
168+
const isRootSpan = span === rootSpan;
168169

169170
// What we do in this glorious piece of code, is hoist any information about parameterized routes from spans emitted
170171
// by Next.js via the `next.route` attribute, up to the transaction by setting the http.route attribute.
@@ -192,13 +193,13 @@ export function init(options: NodeOptions): NodeClient | undefined {
192193

193194
// Add headers to the root span if the client options allow it
194195
const shouldSendDefaultPii = getClient()?.getOptions().sendDefaultPii ?? false;
195-
if (shouldSendDefaultPii && rootSpan) {
196-
const headers = getIsolationScope().getScopeData().sdkProcessingMetadata.normalizedRequest?.headers;
196+
if (shouldSendDefaultPii && isRootSpan) {
197+
const headers = getIsolationScope().getScopeData().sdkProcessingMetadata?.normalizedRequest?.headers;
197198
addHeadersAsAttributes(headers, rootSpan);
198199
}
199200

200201
// We want to fork the isolation scope for incoming requests
201-
if (spanAttributes?.['next.span_type'] === 'BaseServer.handleRequest' && span === getRootSpan(span)) {
202+
if (spanAttributes?.['next.span_type'] === 'BaseServer.handleRequest' && isRootSpan) {
202203
const scopes = getCapturedScopesOnSpan(span);
203204

204205
const isolationScope = (scopes.isolationScope || getIsolationScope()).clone();

0 commit comments

Comments
 (0)