From 9e5bcb26eba8ef19783f9ddb7d1e31bd6831ea11 Mon Sep 17 00:00:00 2001 From: Zoltan Papp Date: Mon, 15 Jun 2026 11:57:34 +0200 Subject: [PATCH] fix(ui): include error name and message in forwarded logs WebKit (macOS WKWebView) omits the "Name: message" header from Error.stack, so forwarding only the stack hid the real cause of failures. Prepend the error name, message and optional cause before the stack so daemon RPC errors surface in gui-client.log. --- client/ui/frontend/src/lib/logs.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/client/ui/frontend/src/lib/logs.ts b/client/ui/frontend/src/lib/logs.ts index 81483056f..6dd8aec42 100644 --- a/client/ui/frontend/src/lib/logs.ts +++ b/client/ui/frontend/src/lib/logs.ts @@ -21,11 +21,25 @@ let inForward = false; let windowStart = 0; let windowCount = 0; +// WebKit (macOS WKWebView) omits the "Name: message" header from Error.stack, +// so a bare stack hides the real cause. Prepend name+message, then the stack. +function formatError(e: Error): string { + const head = `${e.name}: ${e.message}`; + const rawCause = (e as { cause?: unknown }).cause; + const cause = + rawCause instanceof Error + ? `\ncaused by ${rawCause.name}: ${rawCause.message}` + : rawCause !== undefined + ? `\ncaused by ${String(rawCause)}` + : ""; + return e.stack && !e.stack.startsWith(head) ? `${head}${cause}\n${e.stack}` : `${head}${cause}`; +} + function format(args: unknown[]): string { return args .map((a) => { if (typeof a === "string") return a; - if (a instanceof Error) return a.stack || a.message; + if (a instanceof Error) return formatError(a); try { return JSON.stringify(a); } catch {