From cba4a938ecc451c13c7808e0b10ee89abbf27d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Guti=C3=A9rrez?= <35082514+alezmad@users.noreply.github.com> Date: Mon, 4 May 2026 18:34:18 +0100 Subject: [PATCH] chore(cli): keep WS lifecycle diagnostic logs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five info-level log points across the WS lifecycle helper: ws_open_attempt / ws_open_ok / ws_hello_sent / ws_hello_acked / ws_closed (with status + close code/reason). Surfaced during M1 smoke testing — without these the only visible signal was "presence row missing on broker," which made it hard to distinguish "WS never opened" / "opened but hello rejected" / "acked then closed by broker." Both clients prefix the helper-emitted msg ("session_broker_*", "broker_*") so log greps stay clean per role. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/cli/src/daemon/ws-lifecycle.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/cli/src/daemon/ws-lifecycle.ts b/apps/cli/src/daemon/ws-lifecycle.ts index 7a96e40..9522eca 100644 --- a/apps/cli/src/daemon/ws-lifecycle.ts +++ b/apps/cli/src/daemon/ws-lifecycle.ts @@ -143,23 +143,27 @@ export function connectWsWithBackoff(opts: WsLifecycleOptions): Promise((resolve, reject) => { sock.on("open", () => { + log("info", "ws_open_ok", { url: opts.url }); // Build and send the hello inside a microtask so any sync // throws from buildHello() reject this connect attempt cleanly. (async () => { try { const hello = await opts.buildHello(); sock.send(JSON.stringify(hello)); + log("info", "ws_hello_sent", { url: opts.url }); helloTimer = setTimeout(() => { log("warn", "hello_ack_timeout", { url: opts.url }); try { sock.close(); } catch { /* ignore */ } reject(new Error("hello_ack_timeout")); }, helloAckTimeoutMs); } catch (e) { + log("warn", "ws_build_hello_threw", { err: String(e) }); reject(e instanceof Error ? e : new Error(String(e))); } })(); @@ -174,9 +178,8 @@ export function connectWsWithBackoff(opts: WsLifecycleOptions): Promise { if (helloTimer) { clearTimeout(helloTimer); helloTimer = null; } const reasonStr = reason.toString("utf8"); + log("warn", "ws_closed", { url: opts.url, code, reason: reasonStr, status }); opts.onBeforeReconnect?.(code, reasonStr); if (closed) { @@ -200,8 +204,6 @@ export function connectWsWithBackoff(opts: WsLifecycleOptions): Promise openOnce().catch((err) => log("warn", "ws_reconnect_failed", { url: opts.url, err: String(err) })), wait, ); - // First attempt failure (still in connecting) also rejects the - // initial connect promise so callers can surface it. if (status === "connecting" || status === "reconnecting") { reject(new Error(`closed_before_hello_${code}`)); }