Skip to content

Commit 420af8a

Browse files
committed
fix: parameterization backfill
1 parent 9351499 commit 420af8a

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/pages-router-api-endpoints.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ test('Should report an error event for errors thrown in pages router api routes'
88

99
const transactionEventPromise = waitForTransaction('nextjs-13', transactionEvent => {
1010
return (
11-
transactionEvent.transaction === 'GET /api/foo/failure-api-route' &&
11+
transactionEvent.transaction === 'GET /api/[param]/failure-api-route' &&
1212
transactionEvent.contexts?.trace?.op === 'http.server'
1313
);
1414
});

packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
import { captureException, debug, getIsolationScope, httpRequestToRequestData, objectify } from '@sentry/core';
1+
import {
2+
captureException,
3+
debug,
4+
getActiveSpan,
5+
getIsolationScope,
6+
getRootSpan,
7+
httpRequestToRequestData,
8+
objectify,
9+
} from '@sentry/core';
210
import type { NextApiRequest } from 'next';
11+
import { TRANSACTION_ATTR_SENTRY_ROUTE_BACKFILL } from '../span-attributes-with-logic-attached';
312
import type { AugmentedNextApiResponse, NextApiHandler } from '../types';
413
import { flushSafelyWithTimeout } from '../utils/responseEnd';
514

@@ -53,6 +62,14 @@ export function wrapApiHandlerWithSentry(apiHandler: NextApiHandler, parameteriz
5362
normalizedRequest: httpRequestToRequestData(req),
5463
});
5564

65+
// Set the route backfill attribute on the root span so that the transaction name
66+
// gets updated to use the parameterized route during event processing
67+
const activeSpan = getActiveSpan();
68+
if (activeSpan) {
69+
const rootSpan = getRootSpan(activeSpan);
70+
rootSpan.setAttribute(TRANSACTION_ATTR_SENTRY_ROUTE_BACKFILL, parameterizedRoute);
71+
}
72+
5673
return await wrappingTarget.apply(thisArg, args);
5774
} catch (e) {
5875
// In case we have a primitive, wrap it in the equivalent wrapper class (string -> String, etc.) so that we can

packages/nextjs/src/server/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ export function init(options: NodeOptions): NodeClient | undefined {
368368
// backfill transaction name for pages that would otherwise contain unparameterized routes
369369
if (event.contexts.trace.data[TRANSACTION_ATTR_SENTRY_ROUTE_BACKFILL] && event.transaction !== 'GET /_app') {
370370
event.transaction = `${method} ${event.contexts.trace.data[TRANSACTION_ATTR_SENTRY_ROUTE_BACKFILL]}`;
371+
event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] = 'route';
371372
}
372373

373374
const middlewareMatch =

0 commit comments

Comments
 (0)