From 12ba65d6e7edcb304cfaacb03d5e860e61d67b4d Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Tue, 17 Feb 2026 09:43:22 +0700 Subject: [PATCH] fix(app): guard tauri listener cleanup to prevent uncaught unlisten errors --- packages/app/src/hooks/use-file-drop-zone.ts | 19 ++++++++++-- packages/app/src/utils/tauri-window.ts | 31 +++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/packages/app/src/hooks/use-file-drop-zone.ts b/packages/app/src/hooks/use-file-drop-zone.ts index e6df47b3c..b58e93e0a 100644 --- a/packages/app/src/hooks/use-file-drop-zone.ts +++ b/packages/app/src/hooks/use-file-drop-zone.ts @@ -128,6 +128,21 @@ export function useFileDropZone({ let disposed = false; let cleanup: (() => void) | undefined; + let didCleanup = false; + + function runCleanup(unlisten?: () => void | Promise) { + if (didCleanup) return; + const cleanupFn = unlisten ?? cleanup; + if (!cleanupFn) return; + didCleanup = true; + try { + void Promise.resolve(cleanupFn()).catch((error) => { + console.warn("[useFileDropZone] Failed to remove Tauri drag-drop listener:", error); + }); + } catch (error) { + console.warn("[useFileDropZone] Failed to remove Tauri drag-drop listener:", error); + } + } async function setupTauriDragDrop(): Promise { if (!isTauriEnvironment()) { @@ -171,7 +186,7 @@ export function useFileDropZone({ ); if (disposed) { - unlisten(); + runCleanup(unlisten); return true; } @@ -271,7 +286,7 @@ export function useFileDropZone({ return () => { disposed = true; - cleanup?.(); + runCleanup(); }; }, [disabled]); diff --git a/packages/app/src/utils/tauri-window.ts b/packages/app/src/utils/tauri-window.ts index 95aadc764..41a8f86aa 100644 --- a/packages/app/src/utils/tauri-window.ts +++ b/packages/app/src/utils/tauri-window.ts @@ -109,7 +109,21 @@ export function useTrafficLightPadding(): { left: number; top: number } { useEffect(() => { if (Platform.OS !== "web" || !getIsTauriMac()) return; - let unlisten: (() => void) | undefined; + let disposed = false; + let cleanup: (() => void) | undefined; + let didCleanup = false; + + function runCleanup() { + if (!cleanup || didCleanup) return; + didCleanup = true; + try { + void Promise.resolve(cleanup()).catch((error) => { + console.warn("[TauriWindow] Failed to remove resize listener", error); + }); + } catch (error) { + console.warn("[TauriWindow] Failed to remove resize listener", error); + } + } async function setup() { const win = await getTauriWindow(); @@ -117,19 +131,28 @@ export function useTrafficLightPadding(): { left: number; top: number } { // Check initial fullscreen state const fullscreen = await win.isFullscreen(); + if (disposed) return; setIsFullscreen(fullscreen); // Listen for resize events which include fullscreen changes - unlisten = await win.onResized(async () => { + const unlisten = await win.onResized(async () => { + if (disposed) return; const fs = await win.isFullscreen(); + if (disposed) return; setIsFullscreen(fs); }); + + cleanup = unlisten; + if (disposed) { + runCleanup(); + } } - setup(); + void setup(); return () => { - unlisten?.(); + disposed = true; + runCleanup(); }; }, []);