Fix deserialization in read buffer (#225)

* Add deserialization error processing

* Add test
This commit is contained in:
Maria Tigina 2025-08-19 19:00:35 +02:00 • committed by GitHub
commit 9bb851aba2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 1 deletions

View file

@ -1,5 +1,6 @@
package io.modelcontextprotocol.kotlin.sdk.shared
import io.github.oshai.kotlinlogging.KotlinLogging
import io.modelcontextprotocol.kotlin.sdk.JSONRPCMessage
import kotlinx.io.Buffer
import kotlinx.io.indexOf
@ -9,6 +10,9 @@ import kotlinx.io.readString
* Buffers a continuous stdio stream into discrete JSON-RPC messages.
*/
public class ReadBuffer {
private val logger = KotlinLogging.logger { }
private val buffer: Buffer = Buffer()
public fun append(chunk: ByteArray) {
@ -37,7 +41,13 @@ public class ReadBuffer {
string
}
}
return deserializeMessage(line)
try {
return deserializeMessage(line)
} catch (e: Exception) {
logger.error(e) { "Failed to deserialize message from line: $line\nSkipping..." }
}
return null
}
public fun clear() {

View file

@ -45,4 +45,24 @@ class StdioClientTransportTest : BaseTransportTest() {
process.waitFor()
process.destroy()
}
@Test
fun `should ignore first output messages`() = runTest {
val processBuilder = ProcessBuilder("/usr/bin/tee")
val process = processBuilder.start()
process.outputStream.write("Stdio server started".toByteArray())
val input = process.inputStream.asSource().buffered()
val output = process.outputStream.asSink().buffered()
val client = StdioClientTransport(
input = input,
output = output,
)
testClientRead(client)
process.waitFor()
process.destroy()
}
}