diff --git a/Sources/MCP/Base/Error.swift b/Sources/MCP/Base/Error.swift index 0e9a7051..bba1543f 100644 --- a/Sources/MCP/Base/Error.swift +++ b/Sources/MCP/Base/Error.swift @@ -1,5 +1,11 @@ import Foundation +#if canImport(System) + import System +#else + @preconcurrency import SystemPackage +#endif + /// A model context protocol error. public enum Error: Sendable { // Standard JSON-RPC 2.0 errors (-32700 to -32603) @@ -29,6 +35,20 @@ public enum Error: Sendable { case .transportError: return -32001 } } + + /// Check if an error represents a "resource temporarily unavailable" condition + public static func isResourceTemporarilyUnavailable(_ error: Swift.Error) -> Bool { + #if canImport(System) + if let errno = error as? System.Errno, errno == .resourceTemporarilyUnavailable { + return true + } + #else + if let errno = error as? SystemPackage.Errno, errno == .resourceTemporarilyUnavailable { + return true + } + #endif + return false + } } // MARK: LocalizedError diff --git a/Sources/MCP/Base/Transports.swift b/Sources/MCP/Base/Transports.swift index b1c31b64..1cc050c4 100644 --- a/Sources/MCP/Base/Transports.swift +++ b/Sources/MCP/Base/Transports.swift @@ -1,9 +1,14 @@ import Darwin import Logging -import SystemPackage import struct Foundation.Data +#if canImport(System) + import System +#else + @preconcurrency import SystemPackage +#endif + /// Protocol defining the transport layer for MCP communication public protocol Transport: Actor { var logger: Logger { get } @@ -107,7 +112,7 @@ public actor StdioTransport: Transport { messageContinuation.yield(message) } } - } catch let error as Errno where error == .resourceTemporarilyUnavailable { + } catch let error where Error.isResourceTemporarilyUnavailable(error) { try? await Task.sleep(nanoseconds: 10_000_000) // 10ms backoff continue } catch { @@ -147,7 +152,7 @@ public actor StdioTransport: Transport { if written > 0 { remaining = remaining.dropFirst(written) } - } catch let error as Errno where error == .resourceTemporarilyUnavailable { + } catch let error where Error.isResourceTemporarilyUnavailable(error) { try await Task.sleep(nanoseconds: 10_000_000) // 10ms backoff continue } catch { diff --git a/Sources/MCP/Client/Client.swift b/Sources/MCP/Client/Client.swift index c9aa96e7..bd2d2dfb 100644 --- a/Sources/MCP/Client/Client.swift +++ b/Sources/MCP/Client/Client.swift @@ -1,5 +1,4 @@ import Logging -import SystemPackage import struct Foundation.Data import struct Foundation.Date @@ -180,7 +179,7 @@ public actor Client { "Unexpected message received by client", metadata: metadata) } } - } catch let error as Errno where error == .resourceTemporarilyUnavailable { + } catch let error where Error.isResourceTemporarilyUnavailable(error) { try? await Task.sleep(nanoseconds: 10_000_000) // 10ms continue } catch { diff --git a/Sources/MCP/Server/Server.swift b/Sources/MCP/Server/Server.swift index 48f9e336..f93234ed 100644 --- a/Sources/MCP/Server/Server.swift +++ b/Sources/MCP/Server/Server.swift @@ -1,5 +1,4 @@ import Logging -import SystemPackage import struct Foundation.Data import struct Foundation.Date @@ -202,7 +201,7 @@ public actor Server { } throw Error.parseError("Invalid message format") } - } catch let error as Errno where error == .resourceTemporarilyUnavailable { + } catch let error where Error.isResourceTemporarilyUnavailable(error) { // Resource temporarily unavailable, retry after a short delay try? await Task.sleep(nanoseconds: 10_000_000) // 10ms continue diff --git a/Tests/MCPTests/RoundtripTests.swift b/Tests/MCPTests/RoundtripTests.swift index 0de12102..e8bccb9b 100644 --- a/Tests/MCPTests/RoundtripTests.swift +++ b/Tests/MCPTests/RoundtripTests.swift @@ -1,10 +1,15 @@ import Foundation import Logging -import SystemPackage import Testing @testable import MCP +#if canImport(System) + import System +#else + @preconcurrency import SystemPackage +#endif + @Suite("Roundtrip Tests") struct RoundtripTests { @Test( diff --git a/Tests/MCPTests/TransportTests.swift b/Tests/MCPTests/TransportTests.swift index c56f646c..5a2b02ab 100644 --- a/Tests/MCPTests/TransportTests.swift +++ b/Tests/MCPTests/TransportTests.swift @@ -1,9 +1,14 @@ import Foundation -import SystemPackage import Testing @testable import MCP +#if canImport(System) + import System +#else + @preconcurrency import SystemPackage +#endif + @Suite("Stdio Transport Tests") struct StdioTransportTests { @Test("Connection")