From 02d579f0d31319b41bf74fe8afd0d4f73920a79d Mon Sep 17 00:00:00 2001 From: Sergey Karpov Date: Thu, 28 Aug 2025 19:47:18 +0300 Subject: [PATCH 1/2] Add recovery during message deserialization, update workflow, use JUnit Platform for JVM tests --- .github/workflows/validate-pr.yml | 15 ++++++++++++--- .../kotlin/sdk/shared/ReadBuffer.kt | 12 +++++++++++- kotlin-sdk-test/build.gradle.kts | 5 +++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml index 0ab75a73..6bc67341 100644 --- a/.github/workflows/validate-pr.yml +++ b/.github/workflows/validate-pr.yml @@ -3,11 +3,11 @@ name: Validate PR on: workflow_dispatch: pull_request: - branches: [main] + branches: [ main ] concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: validate-pr: @@ -15,17 +15,26 @@ jobs: name: Validate PR steps: - uses: actions/checkout@v4 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: java-version: '21' distribution: 'temurin' + - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - name: Clean Build with Gradle run: ./gradlew clean build + - name: Upload JUnit test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: junit-results + path: '**/build/test-results/test/*.xml' + - name: Disable Auto-Merge on Fail if: failure() run: gh pr merge --disable-auto "$PR_URL" diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt index 6315cb15..1feb9f3f 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt @@ -44,7 +44,17 @@ public class ReadBuffer { try { return deserializeMessage(line) } catch (e: Exception) { - logger.error(e) { "Failed to deserialize message from line: $line\nSkipping..." } + logger.error(e) { "Failed to deserialize message from line: $line\nAttempting to recover..." } + // if there is a non-JSON object prefix, try to parse from the first '{' onward. + val braceIndex = line.indexOf('{') + if (braceIndex != -1) { + val trimmed = line.substring(braceIndex) + try { + return deserializeMessage(trimmed) + } catch (ignored: Exception) { + logger.error(ignored) { "Recovery failed for line: $line\nSkipping..." } + } + } } return null diff --git a/kotlin-sdk-test/build.gradle.kts b/kotlin-sdk-test/build.gradle.kts index ca7e35b3..62d9f365 100644 --- a/kotlin-sdk-test/build.gradle.kts +++ b/kotlin-sdk-test/build.gradle.kts @@ -3,6 +3,11 @@ plugins { } kotlin { + jvm { + testRuns["test"].executionTask.configure { + useJUnitPlatform() + } + } sourceSets { commonTest { dependencies { From f5404147cf8f3c2ac575b5d0b10478d4d0b79983 Mon Sep 17 00:00:00 2001 From: Sergey Karpov Date: Fri, 29 Aug 2025 00:36:27 +0300 Subject: [PATCH 2/2] fixup! Add recovery during message deserialization, update workflow, use JUnit Platform for JVM tests --- .../io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt index 1feb9f3f..014e0eee 100644 --- a/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt +++ b/kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ReadBuffer.kt @@ -52,7 +52,7 @@ public class ReadBuffer { try { return deserializeMessage(trimmed) } catch (ignored: Exception) { - logger.error(ignored) { "Recovery failed for line: $line\nSkipping..." } + logger.error(ignored) { "Deserialization failed for line: $line\nSkipping..." } } } }