From bd5a5798502bef9917e43337986f35bfc774b799 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Wed, 5 Aug 2026 19:08:10 -0700 Subject: [PATCH] fix(browser): close guest reload destruction race --- .../browser-pane/browser-reload-action.test.ts | 18 ++++++++++++++++++ .../browser-pane/browser-reload-action.ts | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/src/renderer/src/components/browser-pane/browser-reload-action.test.ts b/src/renderer/src/components/browser-pane/browser-reload-action.test.ts index fa984a1a081..2f9748767a1 100644 --- a/src/renderer/src/components/browser-pane/browser-reload-action.test.ts +++ b/src/renderer/src/components/browser-pane/browser-reload-action.test.ts @@ -83,6 +83,24 @@ describe('reloadBrowserPageWebview', () => { expect(webview.reload).not.toHaveBeenCalled() }) + it('reports a guest destroyed between the liveness probe and reload', () => { + const getWebContentsId = vi + .fn<() => number>() + .mockReturnValueOnce(42) + .mockImplementation(() => { + throw new Error('WebContents is destroyed') + }) + const webview = createWebview({ + getWebContentsId, + reload: vi.fn(() => { + throw new Error('The WebView must be attached to the DOM') + }) + }) + + expect(reloadBrowserPageWebview(webview, { ignoreCache: false })).toBe('guest-missing') + expect(getWebContentsId).toHaveBeenCalledTimes(2) + }) + // Why: pre-dom-ready reload throws too, but a live guest is already loading — recovery must not replace it. it('reports not-ready when a live guest rejects the reload', () => { const webview = createWebview({ diff --git a/src/renderer/src/components/browser-pane/browser-reload-action.ts b/src/renderer/src/components/browser-pane/browser-reload-action.ts index 53cc08add9b..b4ecb6d9b4f 100644 --- a/src/renderer/src/components/browser-pane/browser-reload-action.ts +++ b/src/renderer/src/components/browser-pane/browser-reload-action.ts @@ -57,6 +57,12 @@ export function reloadBrowserPageWebview( webview.reload() } } catch { + try { + webview.getWebContentsId() + } catch { + // Why: the guest can be destroyed between the liveness probe and reload. + return 'guest-missing' + } return 'not-ready' } return 'reloaded'