1
- import type { Hub } from '@sentry/core' ;
2
- import { getDynamicSamplingContextFromClient } from '@sentry/core' ;
1
+ import { getCurrentHub , getDynamicSamplingContextFromClient } from '@sentry/core' ;
3
2
import type { EventProcessor , Integration , Span } from '@sentry/types' ;
4
3
import {
5
4
dynamicRequire ,
@@ -89,7 +88,7 @@ export class Undici implements Integration {
89
88
/**
90
89
* @inheritDoc
91
90
*/
92
- public setupOnce ( _addGlobalEventProcessor : ( callback : EventProcessor ) => void , getCurrentHub : ( ) => Hub ) : void {
91
+ public setupOnce ( _addGlobalEventProcessor : ( callback : EventProcessor ) => void ) : void {
93
92
// Requires Node 16+ to use the diagnostics_channel API.
94
93
if ( NODE_VERSION . major && NODE_VERSION . major < 16 ) {
95
94
return ;
@@ -107,161 +106,166 @@ export class Undici implements Integration {
107
106
return ;
108
107
}
109
108
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
+ }
114
114
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
+ }
119
120
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
+ }
124
125
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
+ }
131
130
132
- const { request } = message as RequestCreateMessage ;
131
+ private _onRequestCreate = ( message : unknown ) : void => {
132
+ const hub = getCurrentHub ( ) ;
133
+ if ( ! hub . getIntegration ( Undici ) ) {
134
+ return ;
135
+ }
133
136
134
- const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
137
+ const { request } = message as RequestCreateMessage ;
135
138
136
- if ( isSentryRequest ( stringUrl ) || request . __sentry_span__ !== undefined ) {
137
- return ;
138
- }
139
+ const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
139
140
140
- const client = hub . getClient < NodeClient > ( ) ;
141
- if ( ! client ) {
142
- return ;
143
- }
141
+ if ( isSentryRequest ( stringUrl ) || request . __sentry_span__ !== undefined ) {
142
+ return ;
143
+ }
144
144
145
- const clientOptions = client . getOptions ( ) ;
146
- const scope = hub . getScope ( ) ;
145
+ const client = hub . getClient < NodeClient > ( ) ;
146
+ if ( ! client ) {
147
+ return ;
148
+ }
147
149
148
- const parentSpan = scope . getSpan ( ) ;
150
+ const clientOptions = client . getOptions ( ) ;
151
+ const scope = hub . getScope ( ) ;
149
152
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 ;
153
163
}
154
164
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 ;
183
168
}
184
- } ) ;
185
169
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 ) ;
190
187
}
188
+ }
189
+ } ;
191
190
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
+ }
193
196
194
- const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
197
+ const { request, response } = message as RequestEndMessage ;
195
198
196
- if ( isSentryRequest ( stringUrl ) ) {
197
- return ;
198
- }
199
+ const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
199
200
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
+ }
205
204
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 ,
221
219
} ,
222
- ) ;
223
- }
224
- } ) ;
220
+ type : 'http' ,
221
+ } ,
222
+ {
223
+ event : 'response' ,
224
+ request,
225
+ response,
226
+ } ,
227
+ ) ;
228
+ }
229
+ } ;
225
230
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
+ }
231
236
232
- const { request } = message as RequestErrorMessage ;
237
+ const { request } = message as RequestErrorMessage ;
233
238
234
- const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
239
+ const stringUrl = request . origin ? request . origin . toString ( ) + request . path : request . path ;
235
240
236
- if ( isSentryRequest ( stringUrl ) ) {
237
- return ;
238
- }
241
+ if ( isSentryRequest ( stringUrl ) ) {
242
+ return ;
243
+ }
239
244
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
+ }
245
250
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 ,
256
258
} ,
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
+ } ;
265
269
}
266
270
267
271
function setHeadersOnRequest (
0 commit comments