From a32b120c11de7bc24af221ba86a33bea77fcf3d7 Mon Sep 17 00:00:00 2001 From: "buf0-bot[bot]" <252831055+buf0-bot[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 15:25:56 -0700 Subject: [PATCH] fix: address pr-bug-scan findings from #1385 (#1462) Wrapped FirstLaunchBanner handlers' bodies in try/finally so inFlight resets even if fetchSettings rejects, preventing the banner from going permanently inert. Co-authored-by: orca-bug-scan-bot --- .../src/components/FirstLaunchBanner.tsx | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/renderer/src/components/FirstLaunchBanner.tsx b/src/renderer/src/components/FirstLaunchBanner.tsx index 44fa4123d..8a0337978 100644 --- a/src/renderer/src/components/FirstLaunchBanner.tsx +++ b/src/renderer/src/components/FirstLaunchBanner.tsx @@ -71,9 +71,17 @@ export function FirstLaunchBanner({ // banner helper text until the next full relaunch. Mirror // PrivacyPane's handleToggle pattern which refetches for the same // reason before surfacing UI changes. - await acknowledgeBanner() - await fetchSettings() - onResolve() + try { + await acknowledgeBanner() + await fetchSettings() + onResolve() + } finally { + // Why: if `fetchSettings` rejects (IPC error during shutdown, + // settings file lock, etc.), `onResolve` never runs and the banner + // stays mounted. Without resetting `inFlight`, every button stays + // permanently disabled for the rest of the session. + setInFlight(false) + } } const handleTurnOff = async (): Promise => { @@ -86,9 +94,13 @@ export function FirstLaunchBanner({ // `setOptIn` (client.ts). The renderer just needs to route through // `telemetrySetOptIn(false)` so the IPC handler derives the correct // `via` and fires the event. - await telemetrySetOptIn(false) - await fetchSettings() - onResolve() + try { + await telemetrySetOptIn(false) + await fetchSettings() + onResolve() + } finally { + setInFlight(false) + } } return (