fix(desktop): log the latched-failure refusal once in the supervisor, not per request

799a4cc7f2 put a rememberLog before each of the three latched-failure
throws in runHermesStart (main.ts:13257/13262/13270). That path is not
rare while a failure is latched: ensureBackend() calls startHermes()
for every proxied primary API request, and the renderer's boot retries
(BOOT_RETRY_MAX_ATTEMPTS=5) hit it too. Each hit pushed an identical
timestamped line into the 300-line hermesLog ring and the disk flush
buffer, evicting the lines that explain the original failure -- the
same eviction 3f9380daba was fixing.

Remove the per-request lines (runHermesStart's short-circuit is as
cheap and silent as on base, WHY comments kept) and log the refusal
once at the only new consumer that needs the reason: the terminal-latch
early return in runPrimaryRecoverySpawn, which runs once per refused
respawn. Both sites now go through latchedBootFailure() (ordered
bootstrapFailure -> backendStartFailure -> remoteReauthFailure, same
order as before) so the trio can no longer drift between them.

Proof: tsc (tsconfig.electron.json) and eslint clean; vitest 25/25
(backend-start-failure + backend-exit-recovery). Per-request path: the
only rememberLog left in runHermesStart before the E2E block is the
pre-existing non-primary-instance line (awk over the function body);
`grep -c 'latched; refusing restart'` = 0. Helper probe:
(null,null,null)->null, (B,S,R)->B, (null,S,R)->S, (null,null,R)->R.
This commit is contained in:
kshitijk4poor
2026-09-22 13:13:37 +05:30
committed by kshitij
parent 774d851756
commit 88b9d35ee0

View File

@@ -13186,7 +13186,11 @@ function runPrimaryRecoverySpawn(code: number | null, signal: string | null) {
// Terminal boot failures still own their existing recovery UI. Only a
// supervisor-owned respawn that failed transiently before ready may spend
// another bounded recovery slot.
if (bootstrapFailure || backendStartFailure || remoteReauthFailure) {
const latched = latchedBootFailure()
if (latched) {
rememberLog(`[supervisor] respawn refused: boot failure latched: ${firstLine(latched.message)}`)
return
}
@@ -13232,6 +13236,17 @@ function scheduleUnexpectedPrimaryRecovery({
return true
}
/**
* The terminal boot failure currently latched in this process, if any. These
* latches are cleared only by an explicit recovery path (reset, repair,
* apply-config, confirmed sign-in, or the child 'exit' handler), never by a
* retry, so both the per-request short-circuit in runHermesStart and the
* supervisor's respawn refusal must consult the same trio in the same order.
*/
function latchedBootFailure(): Error | null {
return bootstrapFailure ?? backendStartFailure ?? remoteReauthFailure ?? null
}
async function runHermesStart({ supervisorRecovery = false }: { supervisorRecovery?: boolean } = {}) {
// Only the single-instance lock holder may reap/spawn/claim the desktop
// backend. A lock-losing instance must stay inert even if some path reaches
@@ -13253,22 +13268,19 @@ async function runHermesStart({ supervisorRecovery = false }: { supervisorRecove
// ensureGatewayOpen retries (and any other getConnection callers) from
// restarting a 5-10 minute install loop while the user is still reading
// the failure overlay.
if (bootstrapFailure) {
rememberLog(`[boot] bootstrap failure latched; refusing restart: ${firstLine(bootstrapFailure.message)}`)
throw bootstrapFailure
}
//
// A confirmed remote reauth rejection is likewise terminal until the user
// signs in. Short-circuiting here keeps the boot-failure overlay latched and
// its "Sign in" button clickable, instead of re-driving boot on every retry.
//
// Deliberately silent: this runs on every proxied request while a failure is
// latched (ensureBackend -> startHermes), so a log line here would flood the
// bounded rememberLog ring and evict the lines that explain the original
// failure. The supervisor logs the refusal once in runPrimaryRecoverySpawn.
const latched = latchedBootFailure()
if (backendStartFailure) {
rememberLog(`[boot] backend start failure latched; refusing restart: ${firstLine(backendStartFailure.message)}`)
throw backendStartFailure
}
// A confirmed remote reauth rejection is terminal until the user signs in.
// Short-circuiting here keeps the boot-failure overlay latched and its
// "Sign in" button clickable, instead of re-driving boot on every retry.
if (remoteReauthFailure) {
rememberLog(`[boot] remote reauth failure latched; refusing restart: ${firstLine(remoteReauthFailure.message)}`)
throw remoteReauthFailure
if (latched) {
throw latched
}
// E2E: simulate a boot failure without breaking the real backend. The boot