MCPcopy Index your code
hub / github.com/getsentry/sentry-javascript / xhrCallback

Function xhrCallback

packages/browser/src/tracing/request.ts:328–427  ·  view source on GitHub ↗

* Create and track xhr request spans * * @returns Span if a span was created, otherwise void.

(
  handlerData: HandlerDataXhr,
  shouldCreateSpan: (url: string) => boolean,
  shouldAttachHeaders: (url: string) => boolean,
  spans: Record<string, Span>,
  propagateTraceparent?: boolean,
  onRequestSpanEnd?: RequestInstrumentationOptions['onRequestSpanEnd'],
)

Source from the content-addressed store, hash-verified

326 * @returns Span if a span was created, otherwise void.
327 */
328function xhrCallback(
329 handlerData: HandlerDataXhr,
330 shouldCreateSpan: (url: string) => boolean,
331 shouldAttachHeaders: (url: string) => boolean,
332 spans: Record<string, Span>,
333 propagateTraceparent?: boolean,
334 onRequestSpanEnd?: RequestInstrumentationOptions['onRequestSpanEnd'],
335): Span | undefined {
336 const xhr = handlerData.xhr;
337 const sentryXhrData = xhr?.[SENTRY_XHR_DATA_KEY];
338
339 if (!xhr || xhr.__sentry_own_request__ || !sentryXhrData) {
340 return undefined;
341 }
342
343 const { url, method } = sentryXhrData;
344
345 const shouldCreateSpanResult = hasSpansEnabled() && shouldCreateSpan(url);
346
347 // Handle XHR completion - clean up spans from the record
348 if (handlerData.endTimestamp) {
349 const spanId = xhr.__sentry_xhr_span_id__;
350 if (!spanId) return;
351
352 const span = spans[spanId];
353
354 if (span) {
355 if (shouldCreateSpanResult && sentryXhrData.status_code !== undefined) {
356 setHttpStatus(span, sentryXhrData.status_code);
357 span.end();
358
359 onRequestSpanEnd?.(span, {
360 headers: createHeadersSafely(parseXhrResponseHeaders(xhr as XMLHttpRequest & SentryWrappedXMLHttpRequest)),
361 error: handlerData.error,
362 });
363 }
364
365 // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
366 delete spans[spanId];
367 }
368
369 return undefined;
370 }
371
372 const fullUrl = getFullURL(url);
373 const parsedUrl = fullUrl ? parseUrl(fullUrl) : parseUrl(url);
374 const sanitizedFullUrl = fullUrl ? stripDataUrlContent(fullUrl) : undefined;
375
376 const urlForSpanName = stripDataUrlContent(stripUrlQueryAndFragment(url));
377
378 const client = getClient();
379 const hasParent = !!getActiveSpan();
380 // With span streaming, we always emit http.client spans, even without a parent span
381 const shouldEmitSpan = hasParent || (!!client && hasSpanStreamingEnabled(client));
382
383 const span =
384 shouldCreateSpanResult && shouldEmitSpan
385 ? startInactiveSpan({

Callers 1

Calls 15

createHeadersSafelyFunction · 0.90
parseXhrResponseHeadersFunction · 0.90
getFullURLFunction · 0.90
getClientFunction · 0.90
hasSpansEnabledFunction · 0.85
setHttpStatusFunction · 0.85
onRequestSpanEndFunction · 0.85
parseUrlFunction · 0.85
stripDataUrlContentFunction · 0.85
stripUrlQueryAndFragmentFunction · 0.85
hasSpanStreamingEnabledFunction · 0.85
shouldAttachHeadersFunction · 0.85

Tested by

no test coverage detected