Guard system info requests during window teardown#702
Conversation
Fix a race where the renderer could request system:get-system-info while the Electron BrowserWindow was already being destroyed. The IPC handler previously called isMaximized() on a stale BrowserWindow reference, which raised "Object has been destroyed" and surfaced as an unhandled promise rejection in development logs. This change guards the main-process handler with isDestroyed() before reading window state, and wraps the renderer initialization request in try/catch so startup or teardown races do not produce unhandled rejections.
WalkthroughThe pull request adds defensive programming guards to prevent accessing destroyed mainWindow in the main process IPC handler, and wraps renderer-side bridge calls in try-catch error handling with corrected dependency array tracking for proper effect re-execution. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/renderer/components/_templates/app-layout.tsx (1)
31-47: Decouple init calls so one failure doesn’t block unrelated UI state setup.Right now, if
retrieveRecent()fails (Line 33), the already-fetched system info is discarded andsetSystemConfigs/setIsLinuxare skipped. Consider handling these calls independently.♻️ Suggested refactor
useEffect(() => { const getUserSystemProps = async () => { - try { - const { OS, architecture, prefersDarkMode, isWindowMaximized } = await window.bridge.getSystemInfo() - const recent = await window.bridge.retrieveRecent() - - setRecent(recent) - setSystemConfigs({ - OS, - arch: architecture, - shouldUseDarkMode: prefersDarkMode, - isWindowMaximized, - }) - if (OS === 'darwin' || OS === 'win32') { - setIsLinux(false) - } - } catch (error) { - console.error('Failed to read system info during app layout initialization:', error) - } + const [systemInfoResult, recentResult] = await Promise.allSettled([ + window.bridge.getSystemInfo(), + window.bridge.retrieveRecent(), + ]) + + if (systemInfoResult.status === 'fulfilled') { + const { OS, architecture, prefersDarkMode, isWindowMaximized } = systemInfoResult.value + setSystemConfigs({ + OS, + arch: architecture, + shouldUseDarkMode: prefersDarkMode, + isWindowMaximized, + }) + if (OS === 'darwin' || OS === 'win32') { + setIsLinux(false) + } + } else { + console.error('Failed to read system info during app layout initialization:', systemInfoResult.reason) + } + + if (recentResult.status === 'fulfilled') { + setRecent(recentResult.value) + } else { + console.error('Failed to read recent projects during app layout initialization:', recentResult.reason) + } } void getUserSystemProps() }, [setRecent, setSystemConfigs])🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/renderer/components/_templates/app-layout.tsx` around lines 31 - 47, The current combined try block around window.bridge.getSystemInfo() and window.bridge.retrieveRecent() causes a failure in retrieveRecent() to prevent setting system state; split these calls so each has its own error handling: call await window.bridge.getSystemInfo() in its own try/catch and always call setSystemConfigs(...) and setIsLinux(...) when getSystemInfo succeeds, then call await window.bridge.retrieveRecent() in a separate try/catch and call setRecent(...) only on success, logging each error independently; reference functions: window.bridge.getSystemInfo, window.bridge.retrieveRecent, setSystemConfigs, setRecent, setIsLinux.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/renderer/components/_templates/app-layout.tsx`:
- Around line 31-47: The current combined try block around
window.bridge.getSystemInfo() and window.bridge.retrieveRecent() causes a
failure in retrieveRecent() to prevent setting system state; split these calls
so each has its own error handling: call await window.bridge.getSystemInfo() in
its own try/catch and always call setSystemConfigs(...) and setIsLinux(...) when
getSystemInfo succeeds, then call await window.bridge.retrieveRecent() in a
separate try/catch and call setRecent(...) only on success, logging each error
independently; reference functions: window.bridge.getSystemInfo,
window.bridge.retrieveRecent, setSystemConfigs, setRecent, setIsLinux.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 7d3a8c55-8b1d-4185-94ff-6bef2dddc0b9
📒 Files selected for processing (2)
src/main/modules/ipc/main.tssrc/renderer/components/_templates/app-layout.tsx
|
I updated PR #702 by merging the latest development branch and resolving the merge conflict. The app layout initialization change is preserved in the new frontend path, with separate error handling for system info and recent projects. The PR is now mergeable again from a code/conflict standpoint. |
Pull request info
References
If applicable substitute the issue reference to the one that this PR refers
This PR resolve the N/A.
Link to Jira task
N/A
Description of the changes proposed
system:get-system-infoin the main process whenmainWindowis missing or already destroyedObject has been destroyederrors during BrowserWindow teardownretrieveRecent()does not block system state setupDOD checklist