diff --git a/CHANGELOG.md b/CHANGELOG.md index 2deec286efe..69219fc474b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,9 @@ - This allows spans to be filtered by span origin on creation - Honor ignored span origins in `SentryTracer.startChild` ([#3704](https://github.com/getsentry/sentry-java/pull/3704)) - Add `enable-spotlight` and `spotlight-connection-url` to external options and check if spotlight is enabled when deciding whether to inspect an OpenTelemetry span for connecting to splotlight ([#3709](https://github.com/getsentry/sentry-java/pull/3709)) +- Trace context on `Contexts.setTrace` has been marked `@NotNull` ([#3721](https://github.com/getsentry/sentry-java/pull/3721)) + - Setting it to `null` would cause an exception. + - Transactions are dropped if trace context is missing ### Behavioural Changes diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2EventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2EventProcessorTest.kt index 5d487cf3426..d930333f4c2 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2EventProcessorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AnrV2EventProcessorTest.kt @@ -115,7 +115,7 @@ class AnrV2EventProcessorTest { persistScope( CONTEXTS_FILENAME, Contexts().apply { - trace = SpanContext("test") + setTrace(SpanContext("test")) setResponse(Response().apply { bodySize = 1024 }) setBrowser(Browser().apply { name = "Google Chrome" }) } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt index b9455d19deb..0d969360225 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/PerformanceAndroidEventProcessorTest.kt @@ -873,7 +873,7 @@ class PerformanceAndroidEventProcessorTest { AppStartType.UNKNOWN -> "ui.load" } val txn = SentryTransaction(fixture.tracer) - txn.contexts.trace = SpanContext(op, TracesSamplingDecision(false)) + txn.contexts.setTrace(SpanContext(op, TracesSamplingDecision(false))) return txn } } diff --git a/sentry/src/main/java/io/sentry/CombinedContextsView.java b/sentry/src/main/java/io/sentry/CombinedContextsView.java index 3720fa5b93d..b5445784c03 100644 --- a/sentry/src/main/java/io/sentry/CombinedContextsView.java +++ b/sentry/src/main/java/io/sentry/CombinedContextsView.java @@ -50,7 +50,7 @@ public CombinedContextsView( } @Override - public void setTrace(@Nullable SpanContext traceContext) { + public void setTrace(@NotNull SpanContext traceContext) { getDefaultContexts().setTrace(traceContext); } diff --git a/sentry/src/main/java/io/sentry/MonitorContexts.java b/sentry/src/main/java/io/sentry/MonitorContexts.java index 00ccb680fc3..34838c3ea53 100644 --- a/sentry/src/main/java/io/sentry/MonitorContexts.java +++ b/sentry/src/main/java/io/sentry/MonitorContexts.java @@ -39,7 +39,7 @@ public MonitorContexts(final @NotNull MonitorContexts contexts) { return toContextType(SpanContext.TYPE, SpanContext.class); } - public void setTrace(final @Nullable SpanContext traceContext) { + public void setTrace(final @NotNull SpanContext traceContext) { Objects.requireNonNull(traceContext, "traceContext is required"); this.put(SpanContext.TYPE, traceContext); } diff --git a/sentry/src/main/java/io/sentry/protocol/Contexts.java b/sentry/src/main/java/io/sentry/protocol/Contexts.java index fcfb35eb436..53c97bcb0b0 100644 --- a/sentry/src/main/java/io/sentry/protocol/Contexts.java +++ b/sentry/src/main/java/io/sentry/protocol/Contexts.java @@ -72,7 +72,7 @@ public Contexts(final @NotNull Contexts contexts) { return toContextType(SpanContext.TYPE, SpanContext.class); } - public void setTrace(final @Nullable SpanContext traceContext) { + public void setTrace(final @NotNull SpanContext traceContext) { Objects.requireNonNull(traceContext, "traceContext is required"); this.put(SpanContext.TYPE, traceContext); } diff --git a/sentry/src/test/java/io/sentry/CheckInSerializationTest.kt b/sentry/src/test/java/io/sentry/CheckInSerializationTest.kt index 2e8c8d71fc8..db113fa009c 100644 --- a/sentry/src/test/java/io/sentry/CheckInSerializationTest.kt +++ b/sentry/src/test/java/io/sentry/CheckInSerializationTest.kt @@ -22,11 +22,13 @@ class CheckInSerializationTest { fun getSut(type: MonitorScheduleType): CheckIn { return CheckIn("some_slug", CheckInStatus.ERROR).apply { - contexts.trace = TransactionContext.fromPropagationContext( - PropagationContext().also { - it.traceId = SentryId("f382e3180c714217a81371f8c644aefe") - it.spanId = SpanId("85694b9f567145a6") - } + contexts.setTrace( + TransactionContext.fromPropagationContext( + PropagationContext().also { + it.traceId = SentryId("f382e3180c714217a81371f8c644aefe") + it.spanId = SpanId("85694b9f567145a6") + } + ) ) duration = 12.3 environment = "env" diff --git a/sentry/src/test/java/io/sentry/CombinedContextsViewTest.kt b/sentry/src/test/java/io/sentry/CombinedContextsViewTest.kt index 624ca2417d8..b70e9506a8f 100644 --- a/sentry/src/test/java/io/sentry/CombinedContextsViewTest.kt +++ b/sentry/src/test/java/io/sentry/CombinedContextsViewTest.kt @@ -37,7 +37,7 @@ class CombinedContextsViewTest { fun `uses default context CURRENT`() { fixture.getSut() val combined = CombinedContextsView(fixture.global, fixture.isolation, fixture.current, ScopeType.CURRENT) - combined.trace = SpanContext("some") + combined.setTrace(SpanContext("some")) assertEquals("some", fixture.current.trace?.op) } @@ -45,7 +45,7 @@ class CombinedContextsViewTest { fun `uses default context ISOLATION`() { fixture.getSut() val combined = CombinedContextsView(fixture.global, fixture.isolation, fixture.current, ScopeType.ISOLATION) - combined.trace = SpanContext("some") + combined.setTrace(SpanContext("some")) assertEquals("some", fixture.isolation.trace?.op) } @@ -53,16 +53,16 @@ class CombinedContextsViewTest { fun `uses default context GLOBAL`() { fixture.getSut() val combined = CombinedContextsView(fixture.global, fixture.isolation, fixture.current, ScopeType.GLOBAL) - combined.trace = SpanContext("some") + combined.setTrace(SpanContext("some")) assertEquals("some", fixture.global.trace?.op) } @Test fun `prefers trace from current context`() { val combined = fixture.getSut() - fixture.current.trace = SpanContext("current") - fixture.isolation.trace = SpanContext("isolation") - fixture.global.trace = SpanContext("global") + fixture.current.setTrace(SpanContext("current")) + fixture.isolation.setTrace(SpanContext("isolation")) + fixture.global.setTrace(SpanContext("global")) assertEquals("current", combined.trace?.op) } @@ -70,8 +70,8 @@ class CombinedContextsViewTest { @Test fun `uses isolation trace if current context does not have it`() { val combined = fixture.getSut() - fixture.isolation.trace = SpanContext("isolation") - fixture.global.trace = SpanContext("global") + fixture.isolation.setTrace(SpanContext("isolation")) + fixture.global.setTrace(SpanContext("global")) assertEquals("isolation", combined.trace?.op) } @@ -79,7 +79,7 @@ class CombinedContextsViewTest { @Test fun `uses global trace if current and isolation context do not have it`() { val combined = fixture.getSut() - fixture.global.trace = SpanContext("global") + fixture.global.setTrace(SpanContext("global")) assertEquals("global", combined.trace?.op) } @@ -87,7 +87,7 @@ class CombinedContextsViewTest { @Test fun `sets trace on default context`() { val combined = fixture.getSut() - combined.trace = SpanContext("some") + combined.setTrace(SpanContext("some")) assertNull(fixture.current.trace) assertEquals("some", fixture.isolation.trace?.op) @@ -414,7 +414,7 @@ class CombinedContextsViewTest { @Test fun `size combines contexts`() { val combined = fixture.getSut() - fixture.current.trace = SpanContext("current") + fixture.current.setTrace(SpanContext("current")) fixture.isolation.setApp(App().also { it.appName = "isolation" }) fixture.global.setGpu(Gpu().also { it.name = "global" }) @@ -424,9 +424,9 @@ class CombinedContextsViewTest { @Test fun `size considers overrides`() { val combined = fixture.getSut() - fixture.current.trace = SpanContext("current") - fixture.isolation.trace = SpanContext("isolation") - fixture.global.trace = SpanContext("global") + fixture.current.setTrace(SpanContext("current")) + fixture.isolation.setTrace(SpanContext("isolation")) + fixture.global.setTrace(SpanContext("global")) assertEquals(1, combined.size) } @@ -440,7 +440,7 @@ class CombinedContextsViewTest { @Test fun `isNotEmpty if current has value`() { val combined = fixture.getSut() - fixture.current.trace = SpanContext("current") + fixture.current.setTrace(SpanContext("current")) assertFalse(combined.isEmpty) } @@ -470,28 +470,28 @@ class CombinedContextsViewTest { @Test fun `containsKey current`() { val combined = fixture.getSut() - fixture.current.trace = SpanContext("current") + fixture.current.setTrace(SpanContext("current")) assertTrue(combined.containsKey("trace")) } @Test fun `containsKey isolation`() { val combined = fixture.getSut() - fixture.isolation.trace = SpanContext("isolation") + fixture.isolation.setTrace(SpanContext("isolation")) assertTrue(combined.containsKey("trace")) } @Test fun `containsKey global`() { val combined = fixture.getSut() - fixture.global.trace = SpanContext("global") + fixture.global.setTrace(SpanContext("global")) assertTrue(combined.containsKey("trace")) } @Test fun `keys combines contexts`() { val combined = fixture.getSut() - fixture.current.trace = SpanContext("current") + fixture.current.setTrace(SpanContext("current")) fixture.isolation.setApp(App().also { it.appName = "isolation" }) fixture.global.setGpu(Gpu().also { it.name = "global" }) @@ -502,7 +502,7 @@ class CombinedContextsViewTest { fun `entrySet combines contexts`() { val combined = fixture.getSut() val trace = SpanContext("current") - fixture.current.trace = trace + fixture.current.setTrace(trace) val app = App().also { it.appName = "isolation" } fixture.isolation.setApp(app) val gpu = Gpu().also { it.name = "global" } diff --git a/sentry/src/test/java/io/sentry/ScopesTest.kt b/sentry/src/test/java/io/sentry/ScopesTest.kt index 54f8c9725bc..236912291d0 100644 --- a/sentry/src/test/java/io/sentry/ScopesTest.kt +++ b/sentry/src/test/java/io/sentry/ScopesTest.kt @@ -425,7 +425,7 @@ class ScopesTest { val event = SentryEvent(exception) val originalSpanContext = SpanContext("op") - event.contexts.trace = originalSpanContext + event.contexts.setTrace(originalSpanContext) val hints = HintUtils.createWithTypeCheckHint({}) sut.captureEvent(event, hints) diff --git a/sentry/src/test/java/io/sentry/SentryClientTest.kt b/sentry/src/test/java/io/sentry/SentryClientTest.kt index 88a6a1adc6a..881d99bbe58 100644 --- a/sentry/src/test/java/io/sentry/SentryClientTest.kt +++ b/sentry/src/test/java/io/sentry/SentryClientTest.kt @@ -858,7 +858,7 @@ class SentryClientTest { environment = "release" release = "io.sentry.samples@22.1.1" contexts[Contexts.REPLAY_ID] = "64cf554cc8d74c6eafa3e08b7c984f6d" - contexts.trace = SpanContext(traceId, SpanId(), "ui.load", null, null) + contexts.setTrace(SpanContext(traceId, SpanId(), "ui.load", null, null)) transaction = "MainActivity" } val hint = HintUtils.createWithTypeCheckHint(BackfillableHint()) @@ -2496,7 +2496,7 @@ class SentryClientTest { val preExistingSpanContext = SpanContext("op.load") val sentryEvent = SentryEvent() - sentryEvent.contexts.trace = preExistingSpanContext + sentryEvent.contexts.setTrace(preExistingSpanContext) sut.captureEvent(sentryEvent, scope) verify(fixture.transport).send( @@ -2568,7 +2568,7 @@ class SentryClientTest { val preExistingSpanContext = SpanContext("op.load") val sentryEvent = SentryEvent() - sentryEvent.contexts.trace = preExistingSpanContext + sentryEvent.contexts.setTrace(preExistingSpanContext) sut.captureEvent(sentryEvent, scope) verify(fixture.transport).send( diff --git a/sentry/src/test/java/io/sentry/protocol/CombinedContextsViewSerializationTest.kt b/sentry/src/test/java/io/sentry/protocol/CombinedContextsViewSerializationTest.kt index 87cb226abc0..cafcbb8884b 100644 --- a/sentry/src/test/java/io/sentry/protocol/CombinedContextsViewSerializationTest.kt +++ b/sentry/src/test/java/io/sentry/protocol/CombinedContextsViewSerializationTest.kt @@ -24,7 +24,7 @@ class CombinedContextsViewSerializationTest { current.setApp(AppSerializationTest.Fixture().getSut()) current.setBrowser(BrowserSerializationTest.Fixture().getSut()) - current.trace = SpanContextSerializationTest.Fixture().getSut() + current.setTrace(SpanContextSerializationTest.Fixture().getSut()) isolation.setDevice(DeviceSerializationTest.Fixture().getSut()) isolation.setOperatingSystem(OperatingSystemSerializationTest.Fixture().getSut()) diff --git a/sentry/src/test/java/io/sentry/protocol/ContextsSerializationTest.kt b/sentry/src/test/java/io/sentry/protocol/ContextsSerializationTest.kt index ee674790d57..5c9aeb1d375 100644 --- a/sentry/src/test/java/io/sentry/protocol/ContextsSerializationTest.kt +++ b/sentry/src/test/java/io/sentry/protocol/ContextsSerializationTest.kt @@ -22,7 +22,7 @@ class ContextsSerializationTest { setRuntime(SentryRuntimeSerializationTest.Fixture().getSut()) setGpu(GpuSerializationTest.Fixture().getSut()) setResponse(ResponseSerializationTest.Fixture().getSut()) - trace = SpanContextSerializationTest.Fixture().getSut() + setTrace(SpanContextSerializationTest.Fixture().getSut()) } } private val fixture = Fixture() diff --git a/sentry/src/test/java/io/sentry/protocol/ContextsTest.kt b/sentry/src/test/java/io/sentry/protocol/ContextsTest.kt index c1fb47b1c7f..1d0573741fe 100644 --- a/sentry/src/test/java/io/sentry/protocol/ContextsTest.kt +++ b/sentry/src/test/java/io/sentry/protocol/ContextsTest.kt @@ -18,7 +18,7 @@ class ContextsTest { contexts.setRuntime(SentryRuntime()) contexts.setGpu(Gpu()) contexts.setResponse(Response()) - contexts.trace = SpanContext("op") + contexts.setTrace(SpanContext("op")) val clone = Contexts(contexts) @@ -38,7 +38,7 @@ class ContextsTest { fun `copying contexts will have the same values`() { val contexts = Contexts() contexts["some-property"] = "some-value" - contexts.trace = SpanContext("op") + contexts.setTrace(SpanContext("op")) contexts.trace!!.description = "desc" val clone = Contexts(contexts) diff --git a/sentry/src/test/java/io/sentry/protocol/SentryBaseEventSerializationTest.kt b/sentry/src/test/java/io/sentry/protocol/SentryBaseEventSerializationTest.kt index 3da517ef56f..94234c0b340 100644 --- a/sentry/src/test/java/io/sentry/protocol/SentryBaseEventSerializationTest.kt +++ b/sentry/src/test/java/io/sentry/protocol/SentryBaseEventSerializationTest.kt @@ -56,7 +56,7 @@ class SentryBaseEventSerializationTest { setOperatingSystem(OperatingSystemSerializationTest.Fixture().getSut()) setRuntime(SentryRuntimeSerializationTest.Fixture().getSut()) setResponse(ResponseSerializationTest.Fixture().getSut()) - trace = SpanContextSerializationTest.Fixture().getSut() + setTrace(SpanContextSerializationTest.Fixture().getSut()) } sdk = SdkVersionSerializationTest.Fixture().getSut() request = RequestSerializationTest.Fixture().getSut()