Skip to content

Commit 71562fa

Browse files
adinauerclaude
andcommitted
ref(tracing): Extract trace continuation decision into TracingUtils
Move strict trace continuation org-id validation logic to TracingUtils so it can be reused by tracing entry points. Update PropagationContext to call the shared helper and add dedicated TracingUtils tests for strict/non-strict org-id continuation outcomes. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent f7fef22 commit 71562fa

File tree

3 files changed

+85
-27
lines changed

3 files changed

+85
-27
lines changed

sentry/src/main/java/io/sentry/PropagationContext.java

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static PropagationContext fromHeaders(
4545
final @Nullable Baggage baggage,
4646
final @Nullable SpanId spanId,
4747
final @Nullable SentryOptions options) {
48-
if (options != null && !shouldContinueTrace(options, baggage)) {
48+
if (options != null && !TracingUtils.shouldContinueTrace(options, baggage)) {
4949
options
5050
.getLogger()
5151
.log(
@@ -163,30 +163,4 @@ public void setSampled(final @Nullable Boolean sampled) {
163163
return sampleRand == null ? 0.0 : sampleRand;
164164
}
165165

166-
static boolean shouldContinueTrace(
167-
final @NotNull SentryOptions options, final @Nullable Baggage baggage) {
168-
final @Nullable String rawSdkOrgId = options.getEffectiveOrgId();
169-
final @Nullable String sdkOrgId =
170-
(rawSdkOrgId != null && !rawSdkOrgId.trim().isEmpty()) ? rawSdkOrgId.trim() : null;
171-
final @Nullable String rawBaggageOrgId = baggage != null ? baggage.getOrgId() : null;
172-
final @Nullable String baggageOrgId =
173-
(rawBaggageOrgId != null && !rawBaggageOrgId.trim().isEmpty())
174-
? rawBaggageOrgId.trim()
175-
: null;
176-
177-
// Mismatched org IDs always reject regardless of strict mode
178-
if (sdkOrgId != null && baggageOrgId != null && !sdkOrgId.equals(baggageOrgId)) {
179-
return false;
180-
}
181-
182-
// In strict mode, both must be present and match (unless both are missing)
183-
if (options.isStrictTraceContinuation()) {
184-
if (sdkOrgId == null && baggageOrgId == null) {
185-
return true;
186-
}
187-
return sdkOrgId != null && sdkOrgId.equals(baggageOrgId);
188-
}
189-
190-
return true;
191-
}
192166
}

sentry/src/main/java/io/sentry/util/TracingUtils.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,34 @@ public static boolean isIgnored(
196196
return false;
197197
}
198198

199+
@ApiStatus.Internal
200+
public static boolean shouldContinueTrace(
201+
final @NotNull SentryOptions options, final @Nullable Baggage baggage) {
202+
final @Nullable String rawSdkOrgId = options.getEffectiveOrgId();
203+
final @Nullable String sdkOrgId =
204+
(rawSdkOrgId != null && !rawSdkOrgId.trim().isEmpty()) ? rawSdkOrgId.trim() : null;
205+
final @Nullable String rawBaggageOrgId = baggage != null ? baggage.getOrgId() : null;
206+
final @Nullable String baggageOrgId =
207+
(rawBaggageOrgId != null && !rawBaggageOrgId.trim().isEmpty())
208+
? rawBaggageOrgId.trim()
209+
: null;
210+
211+
// Mismatched org IDs always reject regardless of strict mode
212+
if (sdkOrgId != null && baggageOrgId != null && !sdkOrgId.equals(baggageOrgId)) {
213+
return false;
214+
}
215+
216+
// In strict mode, both must be present and match (unless both are missing)
217+
if (options.isStrictTraceContinuation()) {
218+
if (sdkOrgId == null && baggageOrgId == null) {
219+
return true;
220+
}
221+
return sdkOrgId != null && sdkOrgId.equals(baggageOrgId);
222+
}
223+
224+
return true;
225+
}
226+
199227
/**
200228
* Ensures a non null baggage instance is present by creating a new Baggage instance if null is
201229
* passed in.

sentry/src/test/java/io/sentry/util/TracingUtilsTest.kt

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,4 +510,60 @@ class TracingUtilsTest {
510510
assertEquals(fixture.scope.propagationContext.spanId.toString(), parts[2])
511511
assertEquals("00", parts[3])
512512
}
513+
514+
private fun makeOptions(
515+
dsnOrgId: String?,
516+
explicitOrgId: String? = null,
517+
strict: Boolean = false,
518+
): SentryOptions {
519+
val options = SentryOptions()
520+
if (dsnOrgId != null) {
521+
options.dsn = "https://key@o$dsnOrgId.ingest.sentry.io/123"
522+
} else {
523+
options.dsn = "https://key@sentry.io/123"
524+
}
525+
options.orgId = explicitOrgId
526+
options.isStrictTraceContinuation = strict
527+
return options
528+
}
529+
530+
private fun makeBaggage(orgId: String?): Baggage {
531+
val raw =
532+
if (orgId != null) {
533+
"sentry-trace_id=bc6d53f15eb88f4320054569b8c553d4,sentry-org_id=$orgId"
534+
} else {
535+
"sentry-trace_id=bc6d53f15eb88f4320054569b8c553d4"
536+
}
537+
return Baggage.fromHeader(raw, NoOpLogger.getInstance())
538+
}
539+
540+
@Test
541+
fun `shouldContinueTrace strict=false matching org ids returns true`() {
542+
val options = makeOptions(dsnOrgId = "1", strict = false)
543+
assertTrue(TracingUtils.shouldContinueTrace(options, makeBaggage("1")))
544+
}
545+
546+
@Test
547+
fun `shouldContinueTrace strict=false mismatched org ids returns false`() {
548+
val options = makeOptions(dsnOrgId = "2", strict = false)
549+
assertFalse(TracingUtils.shouldContinueTrace(options, makeBaggage("1")))
550+
}
551+
552+
@Test
553+
fun `shouldContinueTrace strict=true matching org ids returns true`() {
554+
val options = makeOptions(dsnOrgId = "1", strict = true)
555+
assertTrue(TracingUtils.shouldContinueTrace(options, makeBaggage("1")))
556+
}
557+
558+
@Test
559+
fun `shouldContinueTrace strict=true missing baggage org id returns false`() {
560+
val options = makeOptions(dsnOrgId = "1", strict = true)
561+
assertFalse(TracingUtils.shouldContinueTrace(options, makeBaggage(null)))
562+
}
563+
564+
@Test
565+
fun `shouldContinueTrace strict=true both missing org ids returns true`() {
566+
val options = makeOptions(dsnOrgId = null, strict = true)
567+
assertTrue(TracingUtils.shouldContinueTrace(options, makeBaggage(null)))
568+
}
513569
}

0 commit comments

Comments
 (0)