1- import type { Hub } from '@sentry/core' ;
2- import { getDynamicSamplingContextFromClient } from '@sentry/core' ;
1+ import { getCurrentHub , getDynamicSamplingContextFromClient } from '@sentry/core' ;
32import type { EventProcessor , Integration , Span } from '@sentry/types' ;
43import {
54 dynamicRequire ,
@@ -89,7 +88,7 @@ export class Undici implements Integration {
8988 /**
9089 * @inheritDoc
9190 */
92- public setupOnce ( _addGlobalEventProcessor : ( callback : EventProcessor ) => void , getCurrentHub : ( ) => Hub ) : void {
91+ public setupOnce ( _addGlobalEventProcessor : ( callback : EventProcessor ) => void ) : void {
9392 // Requires Node 16+ to use the diagnostics_channel API.
9493 if ( NODE_VERSION . major && NODE_VERSION . major < 16 ) {
9594 return ;
@@ -107,161 +106,166 @@ export class Undici implements Integration {
107106 return ;
108107 }
109108
110- const shouldCreateSpan = ( url : string ) : boolean => {
111- if ( this . _options . shouldCreateSpanForRequest === undefined ) {
112- return true ;
113- }
109+ // https://github.com/nodejs/undici/blob/e6fc80f809d1217814c044f52ed40ef13f21e43c/docs/api/DiagnosticsChannel.md
110+ ds . subscribe ( ChannelName . RequestCreate , this . _onRequestCreate ) ;
111+ ds . subscribe ( ChannelName . RequestEnd , this . _onRequestEnd ) ;
112+ ds . subscribe ( ChannelName . RequestError , this . _onRequestError ) ;
113+ }
114114
115- const cachedDecision = this . _createSpanUrlMap . get ( url ) ;
116- if ( cachedDecision !== undefined ) {
117- return cachedDecision ;
118- }
115+ /** Helper that wraps shouldCreateSpanForRequest option */
116+ private _shouldCreateSpan ( url : string ) : boolean {
117+ if ( this . _options . shouldCreateSpanForRequest === undefined ) {
118+ return true ;
119+ }
119120
120- const decision = this . _options . shouldCreateSpanForRequest ( url ) ;
121- this . _createSpanUrlMap . set ( url , decision ) ;
122- return decision ;
123- } ;
121+ const cachedDecision = this . _createSpanUrlMap . get ( url ) ;
122+ if ( cachedDecision !== undefined ) {
123+ return cachedDecision ;
124+ }
124125
125- // https://github.com/nodejs/undici/blob/e6fc80f809d1217814c044f52ed40ef13f21e43c/docs/api/DiagnosticsChannel.md
126- ds . subscribe ( ChannelName . RequestCreate , message => {
127- const hub = getCurrentHub ( ) ;
128- if ( ! hub . getIntegration ( Undici ) ) {
129- return ;
130- }
126+ const decision = this . _options . shouldCreateSpanForRequest ( url ) ;
127+ this . _createSpanUrlMap . set ( url , decision ) ;
128+ return decision ;
129+ }
131130
132- const { request } = message as RequestCreateMessage ;
131+ private _onRequestCreate = ( message : unknown ) : void => {
132+ const hub = getCurrentHub ( ) ;
133+ if ( ! hub . getIntegration ( Undici ) ) {
134+ return ;
135+ }
133136
134- const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
137+ const { request } = message as RequestCreateMessage ;
135138
136- if ( isSentryRequest ( stringUrl ) || request . __sentry_span__ !== undefined ) {
137- return ;
138- }
139+ const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
139140
140- const client = hub . getClient < NodeClient > ( ) ;
141- if ( ! client ) {
142- return ;
143- }
141+ if ( isSentryRequest ( stringUrl ) || request . __sentry_span__ !== undefined ) {
142+ return ;
143+ }
144144
145- const clientOptions = client . getOptions ( ) ;
146- const scope = hub . getScope ( ) ;
145+ const client = hub . getClient < NodeClient > ( ) ;
146+ if ( ! client ) {
147+ return ;
148+ }
147149
148- const parentSpan = scope . getSpan ( ) ;
150+ const clientOptions = client . getOptions ( ) ;
151+ const scope = hub . getScope ( ) ;
149152
150- const span = shouldCreateSpan ( stringUrl ) ? createRequestSpan ( parentSpan , request , stringUrl ) : undefined ;
151- if ( span ) {
152- request . __sentry_span__ = span ;
153+ const parentSpan = scope . getSpan ( ) ;
154+
155+ const span = this . _shouldCreateSpan ( stringUrl ) ? createRequestSpan ( parentSpan , request , stringUrl ) : undefined ;
156+ if ( span ) {
157+ request . __sentry_span__ = span ;
158+ }
159+
160+ const shouldAttachTraceData = ( url : string ) : boolean => {
161+ if ( clientOptions . tracePropagationTargets === undefined ) {
162+ return true ;
153163 }
154164
155- const shouldAttachTraceData = ( url : string ) : boolean => {
156- if ( clientOptions . tracePropagationTargets === undefined ) {
157- return true ;
158- }
159-
160- const cachedDecision = this . _headersUrlMap . get ( url ) ;
161- if ( cachedDecision !== undefined ) {
162- return cachedDecision ;
163- }
164-
165- const decision = stringMatchesSomePattern ( url , clientOptions . tracePropagationTargets ) ;
166- this . _headersUrlMap . set ( url , decision ) ;
167- return decision ;
168- } ;
169-
170- if ( shouldAttachTraceData ( stringUrl ) ) {
171- if ( span ) {
172- const dynamicSamplingContext = span ?. transaction ?. getDynamicSamplingContext ( ) ;
173- const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader ( dynamicSamplingContext ) ;
174-
175- setHeadersOnRequest ( request , span . toTraceparent ( ) , sentryBaggageHeader ) ;
176- } else {
177- const { traceId, sampled, dsc } = scope . getPropagationContext ( ) ;
178- const sentryTrace = generateSentryTraceHeader ( traceId , undefined , sampled ) ;
179- const dynamicSamplingContext = dsc || getDynamicSamplingContextFromClient ( traceId , client , scope ) ;
180- const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader ( dynamicSamplingContext ) ;
181- setHeadersOnRequest ( request , sentryTrace , sentryBaggageHeader ) ;
182- }
165+ const cachedDecision = this . _headersUrlMap . get ( url ) ;
166+ if ( cachedDecision !== undefined ) {
167+ return cachedDecision ;
183168 }
184- } ) ;
185169
186- ds . subscribe ( ChannelName . RequestEnd , message => {
187- const hub = getCurrentHub ( ) ;
188- if ( ! hub . getIntegration ( Undici ) ) {
189- return ;
170+ const decision = stringMatchesSomePattern ( url , clientOptions . tracePropagationTargets ) ;
171+ this . _headersUrlMap . set ( url , decision ) ;
172+ return decision ;
173+ } ;
174+
175+ if ( shouldAttachTraceData ( stringUrl ) ) {
176+ if ( span ) {
177+ const dynamicSamplingContext = span ?. transaction ?. getDynamicSamplingContext ( ) ;
178+ const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader ( dynamicSamplingContext ) ;
179+
180+ setHeadersOnRequest ( request , span . toTraceparent ( ) , sentryBaggageHeader ) ;
181+ } else {
182+ const { traceId, sampled, dsc } = scope . getPropagationContext ( ) ;
183+ const sentryTrace = generateSentryTraceHeader ( traceId , undefined , sampled ) ;
184+ const dynamicSamplingContext = dsc || getDynamicSamplingContextFromClient ( traceId , client , scope ) ;
185+ const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader ( dynamicSamplingContext ) ;
186+ setHeadersOnRequest ( request , sentryTrace , sentryBaggageHeader ) ;
190187 }
188+ }
189+ } ;
191190
192- const { request, response } = message as RequestEndMessage ;
191+ private _onRequestEnd = ( message : unknown ) : void => {
192+ const hub = getCurrentHub ( ) ;
193+ if ( ! hub . getIntegration ( Undici ) ) {
194+ return ;
195+ }
193196
194- const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
197+ const { request, response } = message as RequestEndMessage ;
195198
196- if ( isSentryRequest ( stringUrl ) ) {
197- return ;
198- }
199+ const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
199200
200- const span = request . __sentry_span__ ;
201- if ( span ) {
202- span . setHttpStatus ( response . statusCode ) ;
203- span . finish ( ) ;
204- }
201+ if ( isSentryRequest ( stringUrl ) ) {
202+ return ;
203+ }
205204
206- if ( this . _options . breadcrumbs ) {
207- hub . addBreadcrumb (
208- {
209- category : 'http' ,
210- data : {
211- method : request . method ,
212- status_code : response . statusCode ,
213- url : stringUrl ,
214- } ,
215- type : 'http' ,
216- } ,
217- {
218- event : 'response' ,
219- request,
220- response,
205+ const span = request . __sentry_span__ ;
206+ if ( span ) {
207+ span . setHttpStatus ( response . statusCode ) ;
208+ span . finish ( ) ;
209+ }
210+
211+ if ( this . _options . breadcrumbs ) {
212+ hub . addBreadcrumb (
213+ {
214+ category : 'http' ,
215+ data : {
216+ method : request . method ,
217+ status_code : response . statusCode ,
218+ url : stringUrl ,
221219 } ,
222- ) ;
223- }
224- } ) ;
220+ type : 'http' ,
221+ } ,
222+ {
223+ event : 'response' ,
224+ request,
225+ response,
226+ } ,
227+ ) ;
228+ }
229+ } ;
225230
226- ds . subscribe ( ChannelName . RequestError , message => {
227- const hub = getCurrentHub ( ) ;
228- if ( ! hub . getIntegration ( Undici ) ) {
229- return ;
230- }
231+ private _onRequestError = ( message : unknown ) : void => {
232+ const hub = getCurrentHub ( ) ;
233+ if ( ! hub . getIntegration ( Undici ) ) {
234+ return ;
235+ }
231236
232- const { request } = message as RequestErrorMessage ;
237+ const { request } = message as RequestErrorMessage ;
233238
234- const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
239+ const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
235240
236- if ( isSentryRequest ( stringUrl ) ) {
237- return ;
238- }
241+ if ( isSentryRequest ( stringUrl ) ) {
242+ return ;
243+ }
239244
240- const span = request . __sentry_span__ ;
241- if ( span ) {
242- span . setStatus ( 'internal_error' ) ;
243- span . finish ( ) ;
244- }
245+ const span = request . __sentry_span__ ;
246+ if ( span ) {
247+ span . setStatus ( 'internal_error' ) ;
248+ span . finish ( ) ;
249+ }
245250
246- if ( this . _options . breadcrumbs ) {
247- hub . addBreadcrumb (
248- {
249- category : 'http' ,
250- data : {
251- method : request . method ,
252- url : stringUrl ,
253- } ,
254- level : 'error' ,
255- type : 'http' ,
251+ if ( this . _options . breadcrumbs ) {
252+ hub . addBreadcrumb (
253+ {
254+ category : 'http' ,
255+ data : {
256+ method : request . method ,
257+ url : stringUrl ,
256258 } ,
257- {
258- event : 'error' ,
259- request,
260- } ,
261- ) ;
262- }
263- } ) ;
264- }
259+ level : 'error' ,
260+ type : 'http' ,
261+ } ,
262+ {
263+ event : 'error' ,
264+ request,
265+ } ,
266+ ) ;
267+ }
268+ } ;
265269}
266270
267271function setHeadersOnRequest (
0 commit comments