44import { context } from '@opentelemetry/api' ;
55import {
66 applySdkMetadata ,
7+ type Event ,
78 type EventProcessor ,
89 getCapturedScopesOnSpan ,
910 getCurrentScope ,
@@ -18,11 +19,16 @@ import {
1819 setCapturedScopesOnSpan ,
1920 spanToJSON ,
2021 stripUrlQueryAndFragment ,
22+ type TransactionEvent ,
2123} from '@sentry/core' ;
2224import { getScopesFromContext } from '@sentry/opentelemetry' ;
2325import type { VercelEdgeOptions } from '@sentry/vercel-edge' ;
2426import { getDefaultIntegrations , init as vercelEdgeInit } from '@sentry/vercel-edge' ;
25- import { TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION } from '../common/span-attributes-with-logic-attached' ;
27+ import { ATTR_NEXT_SPAN_NAME , ATTR_NEXT_SPAN_TYPE } from '../common/nextSpanAttributes' ;
28+ import {
29+ ATTR_NEXT_PAGES_API_ROUTE_TYPE ,
30+ TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION ,
31+ } from '../common/span-attributes-with-logic-attached' ;
2632import { addHeadersAsAttributes } from '../common/utils/addHeadersAsAttributes' ;
2733import { dropMiddlewareTunnelRequests } from '../common/utils/dropMiddlewareTunnelRequests' ;
2834import { isBuild } from '../common/utils/isBuild' ;
@@ -82,12 +88,21 @@ export function init(options: VercelEdgeOptions = {}): void {
8288 dropMiddlewareTunnelRequests ( span , spanAttributes ) ;
8389
8490 // Mark all spans generated by Next.js as 'auto'
85- if ( spanAttributes ?. [ 'next.span_type' ] !== undefined ) {
91+ if ( spanAttributes ?. [ ATTR_NEXT_SPAN_TYPE ] !== undefined ) {
8692 span . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN , 'auto' ) ;
8793 }
8894
95+ // Backfill span attributes for api route pages because we removed it from the wrapper
96+ if (
97+ spanAttributes ?. [ ATTR_NEXT_SPAN_TYPE ] === 'Node.runHandler' &&
98+ String ( spanAttributes ?. [ 'next.span_name' ] ) . startsWith ( ATTR_NEXT_PAGES_API_ROUTE_TYPE )
99+ ) {
100+ span . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_OP , 'http.server' ) ;
101+ span . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , 'route' ) ;
102+ }
103+
89104 // Make sure middleware spans get the right op
90- if ( spanAttributes ?. [ 'next.span_type' ] === 'Middleware.execute' ) {
105+ if ( spanAttributes ?. [ ATTR_NEXT_SPAN_TYPE ] === 'Middleware.execute' ) {
91106 span . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_OP , 'http.server.middleware' ) ;
92107 span . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , 'url' ) ;
93108
@@ -119,8 +134,8 @@ export function init(options: VercelEdgeOptions = {}): void {
119134 // The otel auto inference will clobber the transaction name because the span has an http.target
120135 if (
121136 event . type === 'transaction' &&
122- event . contexts ?. trace ?. data ?. [ 'next.span_type' ] === 'Middleware.execute' &&
123- event . contexts ?. trace ?. data ?. [ 'next.span_name' ]
137+ event . contexts ?. trace ?. data ?. [ ATTR_NEXT_SPAN_TYPE ] === 'Middleware.execute' &&
138+ event . contexts ?. trace ?. data ?. [ ATTR_NEXT_SPAN_NAME ] !== undefined
124139 ) {
125140 if ( event . transaction ) {
126141 // Older nextjs versions pass the full url appended to the middleware name, which results in high cardinality transaction names.
@@ -139,6 +154,20 @@ export function init(options: VercelEdgeOptions = {}): void {
139154 }
140155 }
141156
157+ // Backfill the transaction name for api route pages because we removed it from the wrapper
158+ if (
159+ event . type === 'transaction' &&
160+ event . contexts ?. trace ?. data ?. [ ATTR_NEXT_SPAN_TYPE ] === 'Node.runHandler' &&
161+ String ( event . contexts . trace . data [ 'next.span_name' ] ) . startsWith ( ATTR_NEXT_PAGES_API_ROUTE_TYPE )
162+ ) {
163+ let path = String ( event . contexts . trace . data [ 'next.span_name' ] ) . replace ( ATTR_NEXT_PAGES_API_ROUTE_TYPE , '' ) . trim ( ) ;
164+ // Set transaction name on isolation scope to ensure parameterized routes are used
165+ // The HTTP server integration sets it on isolation scope, so we need to match that
166+ const method = event . request ?. method || 'GET' ;
167+ path = path ?? event . request ?. url ?? '/' ;
168+ event . transaction = `${ method } ${ path } ` ;
169+ }
170+
142171 setUrlProcessingMetadata ( event ) ;
143172 } ) ;
144173
0 commit comments