From dbe96296de6595d6fb7511563f79db1a0d237897 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Mon, 9 Nov 2026 14:13:47 +0100 Subject: [PATCH 1/2] fix(ktor): Preserve Ktor 3.0 runtime compatibility Avoid inlining Ktor 3.6's AttributeKey factory. The inlined code references a TypeInfo constructor unavailable in older Ktor 3.x runtimes. Construct TypeInfo explicitly through its stable two-argument constructor instead. --- .../java/io/sentry/ktorClient/SentryKtorClientPlugin.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sentry-ktor-client/src/main/java/io/sentry/ktorClient/SentryKtorClientPlugin.kt b/sentry-ktor-client/src/main/java/io/sentry/ktorClient/SentryKtorClientPlugin.kt index 0e4538fb418..0109aeb9fbc 100644 --- a/sentry-ktor-client/src/main/java/io/sentry/ktorClient/SentryKtorClientPlugin.kt +++ b/sentry-ktor-client/src/main/java/io/sentry/ktorClient/SentryKtorClientPlugin.kt @@ -7,6 +7,7 @@ import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.util.* import io.ktor.util.pipeline.* +import io.ktor.util.reflect.TypeInfo import io.sentry.BaggageHeader import io.sentry.BuildConfig import io.sentry.DataCategory @@ -98,9 +99,13 @@ public val SentryKtorClientPlugin: ClientPlugin = // Attributes // Request start time for breadcrumbs - val requestStartTimestampKey = AttributeKey("SentryRequestStartTimestamp") + val requestStartTimestampKey = + AttributeKey( + "SentryRequestStartTimestamp", + TypeInfo(SentryDate::class, null), + ) // Span associated with the request - val requestSpanKey = AttributeKey("SentryRequestSpan") + val requestSpanKey = AttributeKey("SentryRequestSpan", TypeInfo(ISpan::class, null)) onRequest { request, _ -> val effectiveScopes = if (forceScopes) scopes else Sentry.getCurrentScopes() From d28f60a1514dec6aded86daa24a2d61a2b946761 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Wed, 11 Nov 2026 12:05:30 +0100 Subject: [PATCH 2/2] test(ktor): [Ktor 3.6 3] Add Ktor 3.0 compatibility suite (#6520) * test(ktor): Add Ktor 3.0 compatibility suite Compile the production integration against the catalog Ktor version while compiling and running the existing tests against Ktor 3.0.0. Add the compatibility suite to check so inline API binary incompatibilities fail CI. * test(ktor): Simplify Ktor 3.0 suite configuration Use Ktor's enforced platform to pin all compatibility test artifacts to 3.0.0 instead of maintaining a custom resolution strategy. Reuse the standard test source directories so the suite follows source changes. Co-Authored-By: Claude * Update sentry-ktor-client/build.gradle.kts Co-authored-by: Nelson Osacky --------- Co-authored-by: Claude Co-authored-by: Nelson Osacky --- sentry-ktor-client/build.gradle.kts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sentry-ktor-client/build.gradle.kts b/sentry-ktor-client/build.gradle.kts index a28c11eab8d..b4a5cecb05b 100644 --- a/sentry-ktor-client/build.gradle.kts +++ b/sentry-ktor-client/build.gradle.kts @@ -44,6 +44,31 @@ dependencies { testImplementation(libs.okhttp.mockwebserver) } +testing { + suites { + register("testKtor300") { + useJUnit() + dependencies { + implementation(enforcedPlatform("io.ktor:ktor-bom:3.0.0")) + } + sources { + java.setSrcDirs(sourceSets.test.get().java.srcDirs) + resources.setSrcDirs(sourceSets.test.get().resources.srcDirs) + } + } + } +} + +configurations.named("testKtor300Implementation") { + extendsFrom(configurations.testImplementation.get()) +} + +kotlin.target.compilations.named("testKtor300") { + associateWith(kotlin.target.compilations.getByName("main")) +} + +tasks.check { dependsOn(testing.suites.named("testKtor300")) } + buildConfig { useJavaOutput() packageName("io.sentry.ktorClient")