1- import type { TransactionSource } from '@sentry/core' ;
21import {
32 captureException ,
43 getActiveSpan ,
54 getCurrentScope ,
65 getRootSpan ,
76 handleCallbackErrors ,
8- SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ,
9- SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,
107 setCapturedScopesOnSpan ,
11- startSpan ,
128 winterCGRequestToRequestData ,
139 withIsolationScope ,
1410} from '@sentry/core' ;
@@ -17,7 +13,11 @@ import { isPathnameUnderSentryTunnelRoute } from '../common/utils/tunnelPathname
1713import type { EdgeRouteHandler } from '../edge/types' ;
1814
1915/**
20- * Wraps Next.js middleware with Sentry error and performance instrumentation.
16+ * Wraps Next.js middleware with Sentry error instrumentation.
17+ *
18+ * The middleware transaction itself is created by Next.js' native OpenTelemetry instrumentation
19+ * (the `Middleware.execute` span, normalized by `enhanceMiddlewareRootSpan`), so this wrapper no
20+ * longer starts its own span. It only forks an isolation scope, captures errors, and flushes.
2121 *
2222 * @param middleware The middleware handler.
2323 * @returns a wrapped middleware handler.
@@ -32,6 +32,7 @@ export function wrapMiddlewareWithSentry<H extends EdgeRouteHandler>(
3232 ? ( globalThis as Record < string , unknown > ) . _sentryRewritesTunnelPath
3333 : undefined ;
3434
35+ // TODO: This can never work with Turbopack, need to remove it for consistency between builds.
3536 if ( tunnelRoute && typeof tunnelRoute === 'string' ) {
3637 const req : unknown = args [ 0 ] ;
3738 // Check if the current request matches the tunnel route
@@ -52,65 +53,43 @@ export function wrapMiddlewareWithSentry<H extends EdgeRouteHandler>(
5253 }
5354 }
5455 }
56+
5557 // TODO: We still should add central isolation scope creation for when our build-time instrumentation does not work anymore with turbopack.
5658 return withIsolationScope ( isolationScope => {
5759 const req : unknown = args [ 0 ] ;
5860 const currentScope = getCurrentScope ( ) ;
5961
60- let spanName : string ;
61- let spanSource : TransactionSource ;
62-
6362 if ( req instanceof Request ) {
6463 isolationScope . setSDKProcessingMetadata ( {
6564 normalizedRequest : winterCGRequestToRequestData ( req ) ,
6665 } ) ;
67- spanName = `middleware ${ req . method } ` ;
68- spanSource = 'url' ;
66+ currentScope . setTransactionName ( `middleware ${ req . method } ` ) ;
6967 } else {
70- spanName = 'middleware' ;
71- spanSource = 'component' ;
68+ currentScope . setTransactionName ( 'middleware' ) ;
7269 }
7370
74- currentScope . setTransactionName ( spanName ) ;
75-
7671 const activeSpan = getActiveSpan ( ) ;
77-
7872 if ( activeSpan ) {
79- // If there is an active span, it likely means that the automatic Next.js OTEL instrumentation worked and we can
80- // rely on that for parameterization.
81- spanName = 'middleware' ;
82- spanSource = 'component' ;
83-
73+ // If there is an active span, the native Next.js OTEL instrumentation created the middleware root span.
74+ // Bind our forked scopes to it so the transaction picks up the isolation scope instead of the global one.
8475 const rootSpan = getRootSpan ( activeSpan ) ;
8576 if ( rootSpan ) {
8677 setCapturedScopesOnSpan ( rootSpan , currentScope , isolationScope ) ;
8778 }
8879 }
8980
90- return startSpan (
91- {
92- name : spanName ,
93- op : 'http.server.middleware' ,
94- attributes : {
95- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : spanSource ,
96- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.function.nextjs.wrap_middleware' ,
97- } ,
81+ return handleCallbackErrors (
82+ ( ) => wrappingTarget . apply ( thisArg , args ) ,
83+ error => {
84+ captureException ( error , {
85+ mechanism : {
86+ type : 'auto.function.nextjs.wrap_middleware' ,
87+ handled : false ,
88+ } ,
89+ } ) ;
9890 } ,
9991 ( ) => {
100- return handleCallbackErrors (
101- ( ) => wrappingTarget . apply ( thisArg , args ) ,
102- error => {
103- captureException ( error , {
104- mechanism : {
105- type : 'auto.function.nextjs.wrap_middleware' ,
106- handled : false ,
107- } ,
108- } ) ;
109- } ,
110- ( ) => {
111- waitUntil ( flushSafelyWithTimeout ( ) ) ;
112- } ,
113- ) ;
92+ waitUntil ( flushSafelyWithTimeout ( ) ) ;
11493 } ,
11594 ) ;
11695 } ) ;
0 commit comments