mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-21 18:26:09 +00:00
fix(desktop): guard destroyed recovery windows (#37406)
This commit is contained in:
@@ -33,6 +33,7 @@ import {
|
||||
type SidecarListener,
|
||||
} from "./server"
|
||||
import { setupAutoUpdater, showUpdaterDialog } from "./updater"
|
||||
import { safeWebContentsURL } from "./window-state"
|
||||
import {
|
||||
getLastFocusedWindow,
|
||||
registerRendererProtocol,
|
||||
@@ -233,7 +234,7 @@ const main = Effect.gen(function* () {
|
||||
})
|
||||
|
||||
app.on("render-process-gone", (_event, webContents, details) => {
|
||||
writeLog("window", "app render process gone", { url: webContents.getURL(), details }, "error")
|
||||
writeLog("window", "app render process gone", { url: safeWebContentsURL(webContents), details }, "error")
|
||||
})
|
||||
|
||||
setRelaunchHandler(() => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { BrowserWindow } from "electron"
|
||||
import { write as writeLog } from "./logging"
|
||||
import { safeWindowURL } from "./window-state"
|
||||
|
||||
const sampleInterval = 1000
|
||||
const samplePeriod = 15000
|
||||
@@ -46,7 +47,7 @@ export function createUnresponsiveSampler(win: BrowserWindow, name: string) {
|
||||
const message = [
|
||||
"renderer unresponsive samples",
|
||||
`Window: ${name}`,
|
||||
`URL: ${win.isDestroyed() ? "<destroyed>" : win.webContents.getURL()}`,
|
||||
`URL: ${safeWindowURL(win)}`,
|
||||
...entries.map((entry) => `<${entry[1]}> ${entry[0]}`),
|
||||
`Total Samples: ${total}`,
|
||||
].join("\n")
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
export const destroyedWindowURL = "<destroyed>"
|
||||
|
||||
type WebContentsURLState = {
|
||||
isDestroyed(): boolean
|
||||
getURL(): string
|
||||
}
|
||||
|
||||
type WindowURLState = {
|
||||
isDestroyed(): boolean
|
||||
readonly webContents: WebContentsURLState
|
||||
}
|
||||
|
||||
export function safeWebContentsURL(webContents: WebContentsURLState) {
|
||||
try {
|
||||
if (webContents.isDestroyed()) return destroyedWindowURL
|
||||
return webContents.getURL()
|
||||
} catch {
|
||||
return destroyedWindowURL
|
||||
}
|
||||
}
|
||||
|
||||
export function safeWindowURL(win: WindowURLState) {
|
||||
try {
|
||||
if (win.isDestroyed()) return destroyedWindowURL
|
||||
return safeWebContentsURL(win.webContents)
|
||||
} catch {
|
||||
return destroyedWindowURL
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import { getStore, removeStoreFile } from "./store"
|
||||
import { PINCH_ZOOM_ENABLED_KEY, WINDOW_IDS_KEY } from "./store-keys"
|
||||
import { createUnresponsiveSampler } from "./unresponsive"
|
||||
import { createWindowRegistry } from "./window-registry"
|
||||
import { safeWindowURL } from "./window-state"
|
||||
|
||||
const root = dirname(fileURLToPath(import.meta.url))
|
||||
const rendererRoot = join(root, "../renderer")
|
||||
@@ -364,7 +365,7 @@ function wireWindowRecovery(win: BrowserWindow, name: string) {
|
||||
errorCode,
|
||||
errorDescription,
|
||||
validatedURL,
|
||||
currentURL: win.webContents.getURL(),
|
||||
currentURL: safeWindowURL(win),
|
||||
isMainFrame,
|
||||
},
|
||||
"error",
|
||||
@@ -386,12 +387,7 @@ function wireWindowRecovery(win: BrowserWindow, name: string) {
|
||||
})
|
||||
win.webContents.on("render-process-gone", (_event, details) => {
|
||||
sampler.stopAndFlush()
|
||||
writeLog(
|
||||
"window",
|
||||
"renderer process gone",
|
||||
{ window: name, currentURL: win.webContents.getURL(), details },
|
||||
"error",
|
||||
)
|
||||
writeLog("window", "renderer process gone", { window: name, currentURL: safeWindowURL(win), details }, "error")
|
||||
void show(
|
||||
"OpenCode window terminated unexpectedly",
|
||||
[`Window: ${name}`, `Reason: ${details.reason}`, `Code: ${details.exitCode ?? "<unknown>"}`].join("\n"),
|
||||
@@ -399,12 +395,12 @@ function wireWindowRecovery(win: BrowserWindow, name: string) {
|
||||
)
|
||||
})
|
||||
win.on("unresponsive", () => {
|
||||
writeLog("window", "renderer unresponsive", { window: name, currentURL: win.webContents.getURL() }, "error")
|
||||
writeLog("window", "renderer unresponsive", { window: name, currentURL: safeWindowURL(win) }, "error")
|
||||
sampler.start()
|
||||
void show("OpenCode is not responding", "You can relaunch the app, open the logs, or keep waiting.", true)
|
||||
})
|
||||
win.on("responsive", () => {
|
||||
writeLog("window", "renderer responsive", { window: name, currentURL: win.webContents.getURL() }, "error")
|
||||
writeLog("window", "renderer responsive", { window: name, currentURL: safeWindowURL(win) }, "error")
|
||||
sampler.stopAndFlush()
|
||||
})
|
||||
win.webContents.on("console-message", (_event, level, message, line, sourceId) => {
|
||||
|
||||
Reference in New Issue
Block a user