diff --git a/apps/macos/Sources/Clawdis/WebChatServer.swift b/apps/macos/Sources/Clawdis/WebChatServer.swift index f70378eae..9fce94744 100644 --- a/apps/macos/Sources/Clawdis/WebChatServer.swift +++ b/apps/macos/Sources/Clawdis/WebChatServer.swift @@ -61,6 +61,7 @@ final class WebChatServer: @unchecked Sendable { connection.stateUpdateHandler = { state in switch state { case .ready: + webChatServerLogger.debug("WebChatServer connection ready") self.receive(on: connection) case let .failed(error): webChatServerLogger @@ -79,6 +80,9 @@ final class WebChatServer: @unchecked Sendable { self.respond(to: connection, requestData: data) } if isComplete || error != nil { + if let error { + webChatServerLogger.error("WebChatServer receive error: \(error.localizedDescription, privacy: .public)") + } connection.cancel() } else { self.receive(on: connection) @@ -104,6 +108,7 @@ final class WebChatServer: @unchecked Sendable { if path.hasPrefix("webchat/") { path = String(path.dropFirst("webchat/".count)) } + webChatServerLogger.debug("WebChatServer request path=\(path, privacy: .public)") if path.isEmpty { path = "index.html" } guard let root else { diff --git a/apps/macos/Sources/Clawdis/WebChatWindow.swift b/apps/macos/Sources/Clawdis/WebChatWindow.swift index 0a7f5c3f1..68aa64bce 100644 --- a/apps/macos/Sources/Clawdis/WebChatWindow.swift +++ b/apps/macos/Sources/Clawdis/WebChatWindow.swift @@ -105,7 +105,7 @@ final class WebChatWindowController: NSWindowController, WKScriptMessageHandler, self.webView.configuration.userContentController.addUserScript(userScript) WebChatServer.shared.start(root: webChatURL) - guard let baseURL = WebChatServer.shared.baseURL() else { + guard let baseURL = self.waitForWebChatServer() else { webChatLogger.error("WebChatServer not ready; cannot load web chat") return } @@ -114,6 +114,22 @@ final class WebChatWindowController: NSWindowController, WKScriptMessageHandler, webChatLogger.debug("loadPage queued HTML into WKWebView url=\(url.absoluteString, privacy: .public)") } + private func waitForWebChatServer(timeout: TimeInterval = 2.0) -> URL? { + let deadline = Date().addingTimeInterval(timeout) + var base: URL? + while Date() < deadline { + if let url = WebChatServer.shared.baseURL() { + base = url + break + } + RunLoop.current.run(mode: .default, before: Date().addingTimeInterval(0.05)) + } + if base == nil { + webChatLogger.error("WebChatServer failed to become ready within \(timeout, privacy: .public)s") + } + return base + } + func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { webChatLogger.debug("didFinish navigation url=\(webView.url?.absoluteString ?? "nil", privacy: .public)") webView.evaluateJavaScript("document.body.innerText") { result, error in