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

Function createChildOrRootSpan

packages/core/src/tracing/trace.ts:350–453  ·  view source on GitHub ↗
({
  parentSpan,
  spanArguments,
  forceTransaction,
  scope,
}: {
  parentSpan: SentrySpan | undefined;
  spanArguments: SentrySpanArguments;
  forceTransaction?: boolean;
  scope: Scope;
})

Source from the content-addressed store, hash-verified

348}
349
350function createChildOrRootSpan({
351 parentSpan,
352 spanArguments,
353 forceTransaction,
354 scope,
355}: {
356 parentSpan: SentrySpan | undefined;
357 spanArguments: SentrySpanArguments;
358 forceTransaction?: boolean;
359 scope: Scope;
360}): Span {
361 const isolationScope = getIsolationScope();
362
363 if (!hasSpansEnabled()) {
364 const scopePropagationContext = { ...isolationScope.getPropagationContext(), ...scope.getPropagationContext() };
365 const traceId = parentSpan ? parentSpan.spanContext().traceId : scopePropagationContext.traceId;
366
367 // The placeholder is a thin marker; it carries no sampling decision or DSC. Both are read from
368 // the scope: the sampling decision in `getTraceData`, the DSC in `getDynamicSamplingContextFromSpan`.
369 const span = new SentryNonRecordingSpan({ traceId });
370
371 // Nested placeholders link to their parent so `getRootSpan` resolves to the root placeholder,
372 // whose captured scope is the source of truth. Root/forced placeholders are their own root.
373 if (parentSpan && !forceTransaction) {
374 addChildSpanToSpan(parentSpan, span);
375 }
376
377 // Capture scopes so consumers (e.g. SentryTraceProvider) can read them and so the DSC can be
378 // resolved from the scope by `getDynamicSamplingContextFromSpan`. Consistent with `startIdleSpan`.
379 setCapturedScopesOnSpan(span, scope, isolationScope);
380
381 return span;
382 }
383
384 const client = getClient();
385 if (_shouldIgnoreStreamedSpan(client, spanArguments)) {
386 if (!isTracingSuppressed(scope)) {
387 // if tracing is actively suppressed (Sentry.suppressTracing(...)),
388 // we don't want to record a client outcome for the ignored span
389 client?.recordDroppedEvent('ignored', 'span');
390 }
391
392 const ignoredSpan = new SentryNonRecordingSpan({
393 dropReason: 'ignored',
394 traceId: parentSpan?.spanContext().traceId ?? scope.getPropagationContext().traceId,
395 });
396 setCapturedScopesOnSpan(ignoredSpan, scope, isolationScope);
397
398 return ignoredSpan;
399 }
400
401 let span: Span;
402 if (parentSpan && !forceTransaction) {
403 span = _startChildSpan(parentSpan, scope, spanArguments, isolationScope);
404 addChildSpanToSpan(parentSpan, span);
405 } else if (parentSpan) {
406 // If we forced a transaction but have a parent span, make sure to continue from the parent span, not the scope
407 const dsc = getDynamicSamplingContextFromSpan(parentSpan);

Callers 3

startSpanFunction · 0.85
startSpanManualFunction · 0.85
startInactiveSpanFunction · 0.85

Calls 15

getIsolationScopeFunction · 0.90
hasSpansEnabledFunction · 0.90
addChildSpanToSpanFunction · 0.90
setCapturedScopesOnSpanFunction · 0.90
getClientFunction · 0.90
spanIsSampledFunction · 0.90
freezeDscOnSpanFunction · 0.90
logSpanStartFunction · 0.90
_startChildSpanFunction · 0.85
_startRootSpanFunction · 0.85

Tested by

no test coverage detected