From 10e0a6b19673232852473bcefc579a3859a9282f Mon Sep 17 00:00:00 2001 From: Vantz Stockwell Date: Wed, 25 Mar 2026 12:06:34 -0400 Subject: [PATCH] =?UTF-8?q?fix:=20workspace=20restore=20crash=20=E2=80=94?= =?UTF-8?q?=20defer=20to=20setTimeout,=20wrap=20all=20imports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Workspace restore was running synchronously in onMounted which could crash if saved connection IDs were stale. The import of @tauri-apps/api/window for onCloseRequested could also fail in certain contexts. Fix: defer restore to setTimeout(500ms) so the app renders first, wrap each reconnect in individual try/catch, wrap the window close listener setup in try/catch. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/layouts/MainLayout.vue | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 73e4759..e535890 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -438,24 +438,29 @@ onMounted(async () => { document.addEventListener("keydown", handleKeydown); await connectionStore.loadAll(); - // Restore workspace — reconnect saved tabs - try { - const workspace = await invoke<{ tabs: { connectionId: number; protocol: string; position: number }[] } | null>("load_workspace"); - if (workspace?.tabs?.length) { - for (const tab of workspace.tabs.sort((a, b) => a.position - b.position)) { - sessionStore.connect(tab.connectionId).catch(() => {}); + // Restore workspace — reconnect saved tabs (non-blocking, non-fatal) + setTimeout(async () => { + try { + const workspace = await invoke<{ tabs: { connectionId: number; protocol: string; position: number }[] } | null>("load_workspace"); + if (workspace?.tabs?.length) { + for (const tab of workspace.tabs.sort((a, b) => a.position - b.position)) { + try { await sessionStore.connect(tab.connectionId); } catch {} + } } - } - } catch {} + } catch {} + }, 500); - // Save workspace on window close - const appWindow = await import("@tauri-apps/api/window").then(m => m.getCurrentWindow()); - appWindow.onCloseRequested(async () => { - const tabs = sessionStore.sessions - .filter(s => s.protocol === "ssh" || s.protocol === "rdp") - .map((s, i) => ({ connectionId: s.connectionId, protocol: s.protocol, position: i })); - await invoke("save_workspace", { tabs }).catch(() => {}); - }); + // Save workspace on window close (non-fatal) + try { + const { getCurrentWindow } = await import("@tauri-apps/api/window"); + const appWindow = getCurrentWindow(); + appWindow.onCloseRequested(async () => { + const tabs = sessionStore.sessions + .filter(s => s.protocol === "ssh" || s.protocol === "rdp") + .map((s, i) => ({ connectionId: s.connectionId, protocol: s.protocol, position: i })); + await invoke("save_workspace", { tabs }).catch(() => {}); + }); + } catch {} // Check for updates on startup (non-blocking) invoke<{ currentVersion: string; latestVersion: string; updateAvailable: boolean; downloadUrl: string }>("check_for_updates")