@@ -94,97 +94,95 @@ async function instrumentRequest(
9494
9595 const { method, headers } = ctx . request ;
9696
97- const traceCtx = continueTrace ( {
98- sentryTrace : headers . get ( 'sentry-trace' ) || undefined ,
99- baggage : headers . get ( 'baggage' ) ,
100- } ) ;
97+ return continueTrace (
98+ {
99+ sentryTrace : headers . get ( 'sentry-trace' ) || undefined ,
100+ baggage : headers . get ( 'baggage' ) ,
101+ } ,
102+ async ( ) => {
103+ const allHeaders : Record < string , string > = { } ;
101104
102- const allHeaders : Record < string , string > = { } ;
105+ if ( options . trackHeaders ) {
106+ headers . forEach ( ( value , key ) => {
107+ allHeaders [ key ] = value ;
108+ } ) ;
109+ }
103110
104- if ( options . trackHeaders ) {
105- headers . forEach ( ( value , key ) => {
106- allHeaders [ key ] = value ;
107- } ) ;
108- }
111+ if ( options . trackClientIp ) {
112+ getCurrentScope ( ) . setUser ( { ip_address : ctx . clientAddress } ) ;
113+ }
109114
110- if ( options . trackClientIp ) {
111- getCurrentScope ( ) . setUser ( { ip_address : ctx . clientAddress } ) ;
112- }
115+ try {
116+ const interpolatedRoute = interpolateRouteFromUrlAndParams ( ctx . url . pathname , ctx . params ) ;
117+ const source = interpolatedRoute ? 'route' : 'url' ;
118+ // storing res in a variable instead of directly returning is necessary to
119+ // invoke the catch block if next() throws
120+ const res = await startSpan (
121+ {
122+ attributes : {
123+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.http.astro' ,
124+ } ,
125+ name : `${ method } ${ interpolatedRoute || ctx . url . pathname } ` ,
126+ op : 'http.server' ,
127+ status : 'ok' ,
128+ data : {
129+ method,
130+ url : stripUrlQueryAndFragment ( ctx . url . href ) ,
131+ [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : source ,
132+ ...( ctx . url . search && { 'http.query' : ctx . url . search } ) ,
133+ ...( ctx . url . hash && { 'http.fragment' : ctx . url . hash } ) ,
134+ ...( options . trackHeaders && { headers : allHeaders } ) ,
135+ } ,
136+ } ,
137+ async span => {
138+ const originalResponse = await next ( ) ;
113139
114- try {
115- const interpolatedRoute = interpolateRouteFromUrlAndParams ( ctx . url . pathname , ctx . params ) ;
116- const source = interpolatedRoute ? 'route' : 'url' ;
117- // storing res in a variable instead of directly returning is necessary to
118- // invoke the catch block if next() throws
119- const res = await startSpan (
120- {
121- ...traceCtx ,
122- attributes : {
123- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.http.astro' ,
124- } ,
125- name : `${ method } ${ interpolatedRoute || ctx . url . pathname } ` ,
126- op : 'http.server' ,
127- status : 'ok' ,
128- metadata : {
129- // eslint-disable-next-line deprecation/deprecation
130- ...traceCtx ?. metadata ,
131- } ,
132- data : {
133- method,
134- url : stripUrlQueryAndFragment ( ctx . url . href ) ,
135- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : source ,
136- ...( ctx . url . search && { 'http.query' : ctx . url . search } ) ,
137- ...( ctx . url . hash && { 'http.fragment' : ctx . url . hash } ) ,
138- ...( options . trackHeaders && { headers : allHeaders } ) ,
139- } ,
140- } ,
141- async span => {
142- const originalResponse = await next ( ) ;
143-
144- if ( span && originalResponse . status ) {
145- setHttpStatus ( span , originalResponse . status ) ;
146- }
147-
148- const scope = getCurrentScope ( ) ;
149- const client = getClient ( ) ;
150- const contentType = originalResponse . headers . get ( 'content-type' ) ;
151-
152- const isPageloadRequest = contentType && contentType . startsWith ( 'text/html' ) ;
153- if ( ! isPageloadRequest || ! client ) {
154- return originalResponse ;
155- }
156-
157- // Type case necessary b/c the body's ReadableStream type doesn't include
158- // the async iterator that is actually available in Node
159- // We later on use the async iterator to read the body chunks
160- // see https://github.com/microsoft/TypeScript/issues/39051
161- const originalBody = originalResponse . body as NodeJS . ReadableStream | null ;
162- if ( ! originalBody ) {
163- return originalResponse ;
164- }
165-
166- const decoder = new TextDecoder ( ) ;
167-
168- const newResponseStream = new ReadableStream ( {
169- start : async controller => {
170- for await ( const chunk of originalBody ) {
171- const html = typeof chunk === 'string' ? chunk : decoder . decode ( chunk , { stream : true } ) ;
172- const modifiedHtml = addMetaTagToHead ( html , scope , client , span ) ;
173- controller . enqueue ( new TextEncoder ( ) . encode ( modifiedHtml ) ) ;
140+ if ( span && originalResponse . status ) {
141+ setHttpStatus ( span , originalResponse . status ) ;
174142 }
175- controller . close ( ) ;
176- } ,
177- } ) ;
178143
179- return new Response ( newResponseStream , originalResponse ) ;
180- } ,
181- ) ;
182- return res ;
183- } catch ( e ) {
184- sendErrorToSentry ( e ) ;
185- throw e ;
186- }
187- // TODO: flush if serverless (first extract function)
144+ const scope = getCurrentScope ( ) ;
145+ const client = getClient ( ) ;
146+ const contentType = originalResponse . headers . get ( 'content-type' ) ;
147+
148+ const isPageloadRequest = contentType && contentType . startsWith ( 'text/html' ) ;
149+ if ( ! isPageloadRequest || ! client ) {
150+ return originalResponse ;
151+ }
152+
153+ // Type case necessary b/c the body's ReadableStream type doesn't include
154+ // the async iterator that is actually available in Node
155+ // We later on use the async iterator to read the body chunks
156+ // see https://github.com/microsoft/TypeScript/issues/39051
157+ const originalBody = originalResponse . body as NodeJS . ReadableStream | null ;
158+ if ( ! originalBody ) {
159+ return originalResponse ;
160+ }
161+
162+ const decoder = new TextDecoder ( ) ;
163+
164+ const newResponseStream = new ReadableStream ( {
165+ start : async controller => {
166+ for await ( const chunk of originalBody ) {
167+ const html = typeof chunk === 'string' ? chunk : decoder . decode ( chunk , { stream : true } ) ;
168+ const modifiedHtml = addMetaTagToHead ( html , scope , client , span ) ;
169+ controller . enqueue ( new TextEncoder ( ) . encode ( modifiedHtml ) ) ;
170+ }
171+ controller . close ( ) ;
172+ } ,
173+ } ) ;
174+
175+ return new Response ( newResponseStream , originalResponse ) ;
176+ } ,
177+ ) ;
178+ return res ;
179+ } catch ( e ) {
180+ sendErrorToSentry ( e ) ;
181+ throw e ;
182+ }
183+ // TODO: flush if serverless (first extract function)
184+ } ,
185+ ) ;
188186}
189187
190188/**
0 commit comments