diff --git a/Sources/MCP/Base/Error.swift b/Sources/MCP/Base/Error.swift index b7196f07..2d1cde75 100644 --- a/Sources/MCP/Base/Error.swift +++ b/Sources/MCP/Base/Error.swift @@ -237,7 +237,7 @@ extension MCPError: Codable { case -32602: self = .invalidParams(unwrapDetail(message)) case -32603: - self = .internalError(unwrapDetail(nil)) + self = .internalError(unwrapDetail(message)) case -32042: // Extract elicitations array from data var elicitations: [URLElicitationInfo] = [] diff --git a/Tests/MCPTests/ResponseTests.swift b/Tests/MCPTests/ResponseTests.swift index cb918521..165ede71 100644 --- a/Tests/MCPTests/ResponseTests.swift +++ b/Tests/MCPTests/ResponseTests.swift @@ -84,6 +84,29 @@ struct ResponseTests { } } + @Test("Internal error preserves the message from an external server") + func testInternalErrorPreservesMessage() throws { + // A peer sends a -32603 error with a message and no `data.detail`, like + // every other JSON-RPC error. Decoding should keep the message instead + // of dropping it, matching the other standard error cases. + let jsonString = """ + {"jsonrpc":"2.0","id":"test-id","error":{"code":-32603,"message":"Database connection failed"}} + """ + let data = jsonString.data(using: .utf8)! + + let decoder = JSONDecoder() + let decoded = try decoder.decode(Response.self, from: data) + + if case .failure(let decodedError) = decoded.result { + #expect(decodedError.code == -32603) + #expect( + decodedError.localizedDescription + == "Internal error: Database connection failed") + } else { + #expect(Bool(false), "Expected error result") + } + } + @Test("Empty result response encoding") func testEmptyResultResponseEncoding() throws { let response = EmptyMethod.response(id: "test-id")