|
1 | 1 | /* eslint-disable max-lines */ |
2 | | -import { getCurrentHub, getDynamicSamplingContextFromClient, hasTracingEnabled } from '@sentry/core'; |
3 | | -import type { Client, Scope, Span } from '@sentry/types'; |
| 2 | +import { |
| 3 | + getCurrentHub, |
| 4 | + getDynamicSamplingContextFromClient, |
| 5 | + hasTracingEnabled, |
| 6 | + instrumentFetchRequest, |
| 7 | +} from '@sentry/core'; |
| 8 | +import type { Client, HandlerDataFetch, Scope, Span } from '@sentry/types'; |
4 | 9 | import { |
5 | 10 | addInstrumentationHandler, |
6 | 11 | BAGGAGE_HEADER_NAME, |
@@ -66,26 +71,6 @@ export interface RequestInstrumentationOptions { |
66 | 71 | shouldCreateSpanForRequest?(this: void, url: string): boolean; |
67 | 72 | } |
68 | 73 |
|
69 | | -/** Data returned from fetch callback */ |
70 | | -export interface FetchData { |
71 | | - // eslint-disable-next-line @typescript-eslint/no-explicit-any |
72 | | - args: any[]; // the arguments passed to the fetch call itself |
73 | | - fetchData?: { |
74 | | - method: string; |
75 | | - url: string; |
76 | | - // span_id |
77 | | - __span?: string; |
78 | | - }; |
79 | | - |
80 | | - // TODO Should this be unknown instead? If we vendor types, make it a Response |
81 | | - // eslint-disable-next-line @typescript-eslint/no-explicit-any |
82 | | - response?: any; |
83 | | - error?: unknown; |
84 | | - |
85 | | - startTimestamp: number; |
86 | | - endTimestamp?: number; |
87 | | -} |
88 | | - |
89 | 74 | /** Data returned from XHR request */ |
90 | 75 | export interface XHRData { |
91 | 76 | xhr?: { |
@@ -154,8 +139,12 @@ export function instrumentOutgoingRequests(_options?: Partial<RequestInstrumenta |
154 | 139 | const spans: Record<string, Span> = {}; |
155 | 140 |
|
156 | 141 | if (traceFetch) { |
157 | | - addInstrumentationHandler('fetch', (handlerData: FetchData) => { |
158 | | - const createdSpan = fetchCallback(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans); |
| 142 | + addInstrumentationHandler('fetch', (handlerData: HandlerDataFetch) => { |
| 143 | + if (!hasTracingEnabled()) { |
| 144 | + return; |
| 145 | + } |
| 146 | + |
| 147 | + const createdSpan = instrumentFetchRequest(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans); |
159 | 148 | if (enableHTTPTimings && createdSpan) { |
160 | 149 | addHTTPTimings(createdSpan); |
161 | 150 | } |
@@ -276,95 +265,6 @@ export function shouldAttachHeaders(url: string, tracePropagationTargets: (strin |
276 | 265 | return stringMatchesSomePattern(url, tracePropagationTargets || DEFAULT_TRACE_PROPAGATION_TARGETS); |
277 | 266 | } |
278 | 267 |
|
279 | | -/** |
280 | | - * Create and track fetch request spans |
281 | | - * |
282 | | - * @returns Span if a span was created, otherwise void. |
283 | | - */ |
284 | | -export function fetchCallback( |
285 | | - handlerData: FetchData, |
286 | | - shouldCreateSpan: (url: string) => boolean, |
287 | | - shouldAttachHeaders: (url: string) => boolean, |
288 | | - spans: Record<string, Span>, |
289 | | -): Span | undefined { |
290 | | - if (!hasTracingEnabled() || !handlerData.fetchData) { |
291 | | - return undefined; |
292 | | - } |
293 | | - |
294 | | - const shouldCreateSpanResult = shouldCreateSpan(handlerData.fetchData.url); |
295 | | - |
296 | | - if (handlerData.endTimestamp && shouldCreateSpanResult) { |
297 | | - const spanId = handlerData.fetchData.__span; |
298 | | - if (!spanId) return; |
299 | | - |
300 | | - const span = spans[spanId]; |
301 | | - if (span) { |
302 | | - if (handlerData.response) { |
303 | | - // TODO (kmclb) remove this once types PR goes through |
304 | | - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access |
305 | | - span.setHttpStatus(handlerData.response.status); |
306 | | - |
307 | | - const contentLength: string = |
308 | | - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access |
309 | | - handlerData.response && handlerData.response.headers && handlerData.response.headers.get('content-length'); |
310 | | - |
311 | | - const contentLengthNum = parseInt(contentLength); |
312 | | - if (contentLengthNum > 0) { |
313 | | - span.setData('http.response_content_length', contentLengthNum); |
314 | | - } |
315 | | - } else if (handlerData.error) { |
316 | | - span.setStatus('internal_error'); |
317 | | - } |
318 | | - span.finish(); |
319 | | - |
320 | | - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete |
321 | | - delete spans[spanId]; |
322 | | - } |
323 | | - return undefined; |
324 | | - } |
325 | | - |
326 | | - const hub = getCurrentHub(); |
327 | | - const scope = hub.getScope(); |
328 | | - const client = hub.getClient(); |
329 | | - const parentSpan = scope.getSpan(); |
330 | | - |
331 | | - const { method, url } = handlerData.fetchData; |
332 | | - |
333 | | - const span = |
334 | | - shouldCreateSpanResult && parentSpan |
335 | | - ? parentSpan.startChild({ |
336 | | - data: { |
337 | | - url, |
338 | | - type: 'fetch', |
339 | | - 'http.method': method, |
340 | | - }, |
341 | | - description: `${method} ${url}`, |
342 | | - op: 'http.client', |
343 | | - origin: 'auto.http.browser', |
344 | | - }) |
345 | | - : undefined; |
346 | | - |
347 | | - if (span) { |
348 | | - handlerData.fetchData.__span = span.spanId; |
349 | | - spans[span.spanId] = span; |
350 | | - } |
351 | | - |
352 | | - if (shouldAttachHeaders(handlerData.fetchData.url) && client) { |
353 | | - const request: string | Request = handlerData.args[0]; |
354 | | - |
355 | | - // In case the user hasn't set the second argument of a fetch call we default it to `{}`. |
356 | | - handlerData.args[1] = handlerData.args[1] || {}; |
357 | | - |
358 | | - // eslint-disable-next-line @typescript-eslint/no-explicit-any |
359 | | - const options: { [key: string]: any } = handlerData.args[1]; |
360 | | - |
361 | | - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access |
362 | | - options.headers = addTracingHeadersToFetchRequest(request, client, scope, options, span); |
363 | | - } |
364 | | - |
365 | | - return span; |
366 | | -} |
367 | | - |
368 | 268 | /** |
369 | 269 | * Adds sentry-trace and baggage headers to the various forms of fetch headers |
370 | 270 | */ |
|
0 commit comments