Add specific error handling for client connect (#64)
* feat: add specific error handling for client connect * chore: fix typo * feat(tests): Add unit test for client connect function * feat: remove else block to improve readability * feat: remove unneeded file * feat: revert change to misc.xml --------- Co-authored-by: Leonid Stashevsky <e5l@users.noreply.github.com>
This commit is contained in:
parent
a4d765cf94
commit
63288ea63a
2 changed files with 67 additions and 4 deletions
|
|
@ -10,6 +10,7 @@ import kotlinx.serialization.json.JsonElement
|
|||
import kotlinx.serialization.json.JsonNull
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
/**
|
||||
* Options for configuring the MCP client.
|
||||
|
|
@ -100,7 +101,12 @@ public open class Client(
|
|||
notification(InitializedNotification())
|
||||
} catch (error: Throwable) {
|
||||
close()
|
||||
if (error !is CancellationException) {
|
||||
throw IllegalStateException("Error connecting to transport: ${error.message}")
|
||||
}
|
||||
|
||||
throw error
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import io.modelcontextprotocol.kotlin.sdk.CreateMessageResult
|
|||
import io.modelcontextprotocol.kotlin.sdk.EmptyJsonObject
|
||||
import io.modelcontextprotocol.kotlin.sdk.Implementation
|
||||
import InMemoryTransport
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.spyk
|
||||
import io.modelcontextprotocol.kotlin.sdk.InitializeRequest
|
||||
import io.modelcontextprotocol.kotlin.sdk.InitializeResult
|
||||
import io.modelcontextprotocol.kotlin.sdk.JSONRPCMessage
|
||||
|
|
@ -49,13 +51,13 @@ import kotlin.test.fail
|
|||
class ClientTest {
|
||||
@Test
|
||||
fun `should initialize with matching protocol version`() = runTest {
|
||||
var initialied = false
|
||||
var initialised = false
|
||||
val clientTransport = object : AbstractTransport() {
|
||||
override suspend fun start() {}
|
||||
|
||||
override suspend fun send(message: JSONRPCMessage) {
|
||||
if (message !is JSONRPCRequest) return
|
||||
initialied = true
|
||||
initialised = true
|
||||
val result = InitializeResult(
|
||||
protocolVersion = LATEST_PROTOCOL_VERSION,
|
||||
capabilities = ServerCapabilities(),
|
||||
|
|
@ -90,7 +92,7 @@ class ClientTest {
|
|||
)
|
||||
|
||||
client.connect(clientTransport)
|
||||
assertTrue(initialied)
|
||||
assertTrue(initialised)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -189,6 +191,61 @@ class ClientTest {
|
|||
assertTrue(closed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should reject due to non cancellation exception`() = runTest {
|
||||
var closed = false
|
||||
val clientTransport = object : AbstractTransport() {
|
||||
override suspend fun start() {}
|
||||
|
||||
override suspend fun send(message: JSONRPCMessage) {
|
||||
if (message !is JSONRPCRequest) return
|
||||
check(message.method == Method.Defined.Initialize.value)
|
||||
|
||||
val result = InitializeResult(
|
||||
protocolVersion = LATEST_PROTOCOL_VERSION,
|
||||
capabilities = ServerCapabilities(),
|
||||
serverInfo = Implementation(
|
||||
name = "test",
|
||||
version = "1.0"
|
||||
)
|
||||
)
|
||||
|
||||
val response = JSONRPCResponse(
|
||||
id = message.id,
|
||||
result = result
|
||||
)
|
||||
|
||||
_onMessage.invoke(response)
|
||||
}
|
||||
|
||||
override suspend fun close() {
|
||||
closed = true
|
||||
}
|
||||
}
|
||||
|
||||
val mockClient = spyk(
|
||||
Client(
|
||||
clientInfo = Implementation(
|
||||
name = "test client",
|
||||
version = "1.0"
|
||||
),
|
||||
options = ClientOptions()
|
||||
)
|
||||
)
|
||||
|
||||
coEvery{
|
||||
mockClient.request<InitializeResult>(any())
|
||||
} throws IllegalStateException("Test error")
|
||||
|
||||
val exception = assertFailsWith<IllegalStateException> {
|
||||
mockClient.connect(clientTransport)
|
||||
}
|
||||
|
||||
assertEquals("Error connecting to transport: Test error", exception.message)
|
||||
|
||||
assertTrue(closed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should respect server capabilities`() = runTest {
|
||||
val serverOptions = ServerOptions(
|
||||
|
|
|
|||
Loading…
Reference in a new issue