@@ -14,8 +14,14 @@ const queryParsedChannel = channel('apm:next:query-parsed')
14
14
const requests = new WeakSet ( )
15
15
const nodeNextRequestsToNextRequests = new WeakMap ( )
16
16
17
+ // Next.js <= 14.2.6
17
18
const MIDDLEWARE_HEADER = 'x-middleware-invoke'
18
19
20
+ // Next.js >= 14.2.7
21
+ const NEXT_REQUEST_META = Symbol . for ( 'NextInternalRequestMeta' )
22
+ const META_IS_MIDDLEWARE = 'middlewareInvoke'
23
+ const encounteredMiddleware = new WeakSet ( )
24
+
19
25
function wrapHandleRequest ( handleRequest ) {
20
26
return function ( req , res , pathname , query ) {
21
27
return instrument ( req , res , ( ) => handleRequest . apply ( this , arguments ) )
@@ -111,6 +117,11 @@ function getPageFromPath (page, dynamicRoutes = []) {
111
117
return getPagePath ( page )
112
118
}
113
119
120
+ function getRequestMeta ( req , key ) {
121
+ const meta = req [ NEXT_REQUEST_META ] || { }
122
+ return typeof key === 'string' ? meta [ key ] : meta
123
+ }
124
+
114
125
function instrument ( req , res , error , handler ) {
115
126
if ( typeof error === 'function' ) {
116
127
handler = error
@@ -121,8 +132,9 @@ function instrument (req, res, error, handler) {
121
132
res = res . originalResponse || res
122
133
123
134
// TODO support middleware properly in the future?
124
- const isMiddleware = req . headers [ MIDDLEWARE_HEADER ]
125
- if ( isMiddleware || requests . has ( req ) ) {
135
+ const isMiddleware = req . headers [ MIDDLEWARE_HEADER ] || getRequestMeta ( req , META_IS_MIDDLEWARE )
136
+ if ( ( isMiddleware && ! encounteredMiddleware . has ( req ) ) || requests . has ( req ) ) {
137
+ encounteredMiddleware . add ( req )
126
138
if ( error ) {
127
139
errorChannel . publish ( { error } )
128
140
}
@@ -188,7 +200,7 @@ function finish (ctx, result, err) {
188
200
// however, it is not provided as a class function or exported property
189
201
addHook ( {
190
202
name : 'next' ,
191
- versions : [ '>=13.3.0 <14.2.7 ' ] ,
203
+ versions : [ '>=13.3.0 <15 ' ] ,
192
204
file : 'dist/server/web/spec-extension/adapters/next-request.js'
193
205
} , NextRequestAdapter => {
194
206
shimmer . wrap ( NextRequestAdapter . NextRequestAdapter , 'fromNodeNextRequest' , fromNodeNextRequest => {
@@ -203,7 +215,7 @@ addHook({
203
215
204
216
addHook ( {
205
217
name : 'next' ,
206
- versions : [ '>=11.1 <14.2.7 ' ] ,
218
+ versions : [ '>=11.1 <15 ' ] ,
207
219
file : 'dist/server/serve-static.js'
208
220
} , serveStatic => shimmer . wrap ( serveStatic , 'serveStatic' , wrapServeStatic ) )
209
221
@@ -213,7 +225,7 @@ addHook({
213
225
file : 'dist/next-server/server/serve-static.js'
214
226
} , serveStatic => shimmer . wrap ( serveStatic , 'serveStatic' , wrapServeStatic ) )
215
227
216
- addHook ( { name : 'next' , versions : [ '>=11.1 <14.2.7 ' ] , file : 'dist/server/next-server.js' } , nextServer => {
228
+ addHook ( { name : 'next' , versions : [ '>=11.1 <15 ' ] , file : 'dist/server/next-server.js' } , nextServer => {
217
229
const Server = nextServer . default
218
230
219
231
shimmer . wrap ( Server . prototype , 'handleRequest' , wrapHandleRequest )
@@ -230,7 +242,7 @@ addHook({ name: 'next', versions: ['>=11.1 <14.2.7'], file: 'dist/server/next-se
230
242
} )
231
243
232
244
// `handleApiRequest` changes parameters/implementation at 13.2.0
233
- addHook ( { name : 'next' , versions : [ '>=13.2 <14.2.7 ' ] , file : 'dist/server/next-server.js' } , nextServer => {
245
+ addHook ( { name : 'next' , versions : [ '>=13.2 <15 ' ] , file : 'dist/server/next-server.js' } , nextServer => {
234
246
const Server = nextServer . default
235
247
shimmer . wrap ( Server . prototype , 'handleApiRequest' , wrapHandleApiRequestWithMatch )
236
248
return nextServer
@@ -264,7 +276,7 @@ addHook({
264
276
265
277
addHook ( {
266
278
name : 'next' ,
267
- versions : [ '>=13 <14.2.7 ' ] ,
279
+ versions : [ '>=13 <15 ' ] ,
268
280
file : 'dist/server/web/spec-extension/request.js'
269
281
} , request => {
270
282
const nextUrlDescriptor = Object . getOwnPropertyDescriptor ( request . NextRequest . prototype , 'nextUrl' )
0 commit comments