fix(mac): make rpc parsing tolerate stray stdout
This commit is contained in:
@@ -105,9 +105,7 @@ actor AgentRPC {
|
|||||||
stdinHandle.write(data)
|
stdinHandle.write(data)
|
||||||
stdinHandle.write(Data([0x0A]))
|
stdinHandle.write(Data([0x0A]))
|
||||||
|
|
||||||
let line = try await nextLine()
|
let parsed = try await self.nextJSONObject()
|
||||||
let parsed = try JSONSerialization.jsonObject(with: Data(line.utf8)) as? [String: Any]
|
|
||||||
guard let parsed else { throw RpcError(message: "invalid JSON") }
|
|
||||||
|
|
||||||
if let ok = parsed["ok"] as? Bool, let type = parsed["type"] as? String, type == "result" {
|
if let ok = parsed["ok"] as? Bool, let type = parsed["type"] as? String, type == "result" {
|
||||||
if ok {
|
if ok {
|
||||||
@@ -147,10 +145,9 @@ actor AgentRPC {
|
|||||||
stdinHandle.write(data)
|
stdinHandle.write(data)
|
||||||
stdinHandle.write(Data([0x0A]))
|
stdinHandle.write(Data([0x0A]))
|
||||||
|
|
||||||
let line = try await nextLine()
|
let parsed = try await self.nextJSONObject()
|
||||||
let parsed = try JSONSerialization.jsonObject(with: Data(line.utf8)) as? [String: Any]
|
if let ok = parsed["ok"] as? Bool, ok { return (true, nil) }
|
||||||
if let ok = parsed?["ok"] as? Bool, ok { return (true, nil) }
|
return (false, parsed["error"] as? String ?? "rpc status failed: \(parsed)")
|
||||||
return (false, parsed?["error"] as? String ?? "rpc status failed: \(line)")
|
|
||||||
} catch {
|
} catch {
|
||||||
self.logger.error("rpc status failed: \(error.localizedDescription, privacy: .public)")
|
self.logger.error("rpc status failed: \(error.localizedDescription, privacy: .public)")
|
||||||
await self.stop()
|
await self.stop()
|
||||||
@@ -287,6 +284,25 @@ actor AgentRPC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the next line that successfully parses as JSON. Non-JSON lines (e.g., stray stdout logs)
|
||||||
|
/// are skipped to keep the RPC bridge resilient to accidental prints.
|
||||||
|
private func nextJSONObject(maxSkips: Int = 30) async throws -> [String: Any] {
|
||||||
|
var skipped = 0
|
||||||
|
while true {
|
||||||
|
let line = try await self.nextLine()
|
||||||
|
guard let data = line.data(using: .utf8),
|
||||||
|
let obj = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
|
||||||
|
else {
|
||||||
|
skipped += 1
|
||||||
|
if skipped >= maxSkips {
|
||||||
|
throw RpcError(message: "rpc returned non-JSON output: \(line)")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func parseHeartbeatEvent(from line: String) -> HeartbeatEvent? {
|
private func parseHeartbeatEvent(from line: String) -> HeartbeatEvent? {
|
||||||
guard let data = line.data(using: .utf8) else { return nil }
|
guard let data = line.data(using: .utf8) else { return nil }
|
||||||
guard
|
guard
|
||||||
|
|||||||
Reference in New Issue
Block a user