chore(desktop-wsl): log sidecar start failures and flatten server-health logs

The WSL controller previously only stored a failed startup message in its renderer state, so Ubuntu-style silent failures left no trace in main.log. Inject the main-process logger into the controller and emit wsl sidecar ready / wsl sidecar failed to start entries. Also flatten the [server health] renderer logs into a single string argument because Electron's console-message bridge truncates extra args to [object Object].
This commit is contained in:
LukeParkerDev
2026-04-17 15:00:13 +10:00
parent 4560435dd9
commit 11528e43c0
3 changed files with 37 additions and 23 deletions

View File

@@ -203,14 +203,13 @@ export const { use: useServer, provider: ServerProvider } = createSimpleContext(
const check = (conn: ServerConnection.Any) =>
checkServerHealth(conn.http).then((x) => {
if (!x.healthy) {
// Loud: makes it trivial to see why a server shows red in the
// status popover / switcher. The dot only goes red when this
// returns false; otherwise undefined (gray) is emitted first.
console.warn("[server health] unhealthy", {
key: ServerConnection.key(conn),
url: conn.http.url,
hasAuth: !!(conn.http.username || conn.http.password),
})
// Electron's console-message bridge only preserves the first
// console argument, so pre-stringify everything into one string.
console.warn(
`[server health] unhealthy key=${ServerConnection.key(conn)} url=${conn.http.url} hasAuth=${!!(
conn.http.username || conn.http.password
)}`,
)
}
return x.healthy
})
@@ -224,10 +223,7 @@ export const { use: useServer, provider: ServerProvider } = createSimpleContext(
return
}
setState("healthy", undefined)
console.log("[server health] start polling", {
key: ServerConnection.key(current_),
url: current_.http.url,
})
console.log(`[server health] start polling key=${ServerConnection.key(current_)} url=${current_.http.url}`)
onCleanup(startHealthPolling(current_))
})

View File

@@ -56,13 +56,22 @@ const pendingDeepLinks: string[] = []
const serverReady = defer<ServerReadyData>()
void serverReady.promise.catch(() => undefined)
const wslServers = createWslServersController(app.getVersion(), async (distro) => {
const wslServers = (() => {
const logger = initLogging()
logger.log("spawning wsl sidecar", { distro })
return spawnWslSidecar(distro, {
onLine: (line) => logger.log("wsl sidecar", { distro, stream: line.stream, text: line.text }),
})
})
return createWslServersController(
app.getVersion(),
async (distro) => {
logger.log("spawning wsl sidecar", { distro })
return spawnWslSidecar(distro, {
onLine: (line) => logger.log("wsl sidecar", { distro, stream: line.stream, text: line.text }),
})
},
{
log: (message, meta) => logger.log(message, meta),
error: (message, meta) => logger.error(message, meta),
},
)
})()
const logger = initLogging()
logger.log("app starting", {

View File

@@ -41,13 +41,19 @@ type RunningSidecar = {
type SpawnSidecar = (distro: string) => Promise<RunningSidecar>
type ControllerLogger = {
log: (message: string, meta?: unknown) => void
error: (message: string, meta?: unknown) => void
}
export type WslServersController = ReturnType<typeof createWslServersController>
export function wslServerIdForDistro(distro: string) {
return `wsl:${distro}`
}
export function createWslServersController(appVersion: string, spawnSidecar: SpawnSidecar) {
export function createWslServersController(appVersion: string, spawnSidecar: SpawnSidecar, logger?: ControllerLogger) {
const mainLogger: ControllerLogger | undefined = logger
let state: WslServersState = initialState()
const listeners = new Set<(event: WslServersEvent) => void>()
const sidecars = new Map<string, RunningSidecar>()
@@ -124,11 +130,14 @@ export function createWslServersController(appVersion: string, spawnSidecar: Spa
username: sidecar.username,
password: sidecar.password,
})
mainLogger?.log("wsl sidecar ready", { id, distro: item.config.distro, url: sidecar.url })
} catch (error) {
setRuntime(id, {
kind: "failed",
message: error instanceof Error ? error.message : String(error),
})
const message = error instanceof Error ? error.message : String(error)
setRuntime(id, { kind: "failed", message })
// Without this, an Ubuntu-style silent failure leaves no trace in
// main.log — the controller captures the message in its state but
// nothing surfaces unless the user opens the WSL servers dialog.
mainLogger?.error("wsl sidecar failed to start", { id, distro: item.config.distro, message })
}
}