mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-09 19:27:45 +02:00
[eric] browser: guard capture-page on churning webviews to dodge the V8 crash
This commit is contained in:
+14
-2
@@ -2206,8 +2206,20 @@ ipcMain.handle('install-update', async () => {
|
||||
});
|
||||
|
||||
ipcMain.handle('capture-page', async (event, rect) => {
|
||||
const image = await event.sender.capturePage(rect || undefined);
|
||||
return image.toDataURL();
|
||||
// Capturing a webContents whose GPU surface is mid-recycle (a webview navigating
|
||||
// a heavy SPA) can crash the renderer (SharedImage 'non-existent mailbox' ->
|
||||
// V8 ToLocalChecked). The caller now waits for webviews to settle, but guard
|
||||
// here too: skip a gone/crashed/loading sender and never encode an empty image,
|
||||
// returning null so the dashboard keeps its last good preview instead of dying.
|
||||
try {
|
||||
const wc = event.sender;
|
||||
if (!wc || wc.isDestroyed() || wc.isCrashed() || wc.isLoading()) return null;
|
||||
const image = await wc.capturePage(rect || undefined);
|
||||
if (!image || image.isEmpty()) return null;
|
||||
return image.toDataURL();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('open-external', (_event, url) => {
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface BrowserWebview extends HTMLElement {
|
||||
canGoForward: () => boolean;
|
||||
getURL: () => string;
|
||||
getTitle: () => string;
|
||||
isLoading: () => boolean;
|
||||
capturePage: (rect?: { x: number; y: number; width: number; height: number }) => Promise<ElectronNativeImage>;
|
||||
executeJavaScript: (code: string) => Promise<any>;
|
||||
sendInputEvent: (event: any) => void;
|
||||
@@ -64,3 +65,19 @@ export function findBrowserByWebContentsId(wcId: number): string | undefined {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// True if ANY registered webview is mid-navigation. Capturing the dashboard
|
||||
// (which composites live webview pixels) while a webview's GPU surface is being
|
||||
// recycled crashes the renderer (SharedImage 'non-existent mailbox' -> V8
|
||||
// ToLocalChecked), so the thumbnail capture must wait until they've settled.
|
||||
export function anyWebviewLoading(): boolean {
|
||||
for (const wv of registry.values()) {
|
||||
try {
|
||||
if (typeof wv.isLoading === 'function' && wv.isLoading()) return true;
|
||||
} catch {
|
||||
// a torn-down webview can throw; treat as "not safe to capture"
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user