Skip to content

Commit acff577

Browse files
committed
fix: construct tray prefs store lazily inside the hint guard
new Store() reads+writes the prefs file on construction, which can throw on a filesystem error (unreadable/locked path, or a path that is a directory). At module load that would crash the main process before any window opens, and clearInvalidConfig only heals malformed content, not filesystem errors. Construct lazily inside maybeShowTrayHint's existing try/catch so such failures disable the hint instead of crashing startup.
1 parent 5d0ce71 commit acff577

1 file changed

Lines changed: 21 additions & 9 deletions

File tree

src/tray.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,22 @@ let lastHadUnread: boolean | null = null
2323
interface AppPrefsSchema {
2424
hasShownTrayHint: boolean
2525
}
26-
const prefsStore = new Store<AppPrefsSchema>({
27-
name: 'app-prefs',
28-
defaults: { hasShownTrayHint: false },
29-
// Self-heal a corrupt prefs file (reset to defaults) instead of throwing at startup.
30-
clearInvalidConfig: true,
31-
})
26+
// Constructed lazily inside maybeShowTrayHint's try/catch, never at module load:
27+
// `new Store()` reads and writes the prefs file on construction, which can throw
28+
// on an unreadable/locked path or a path that is a directory — that would crash
29+
// the main process before any window opens. (clearInvalidConfig only heals
30+
// malformed content, not filesystem errors.)
31+
let prefsStore: Store<AppPrefsSchema> | null = null
32+
function getPrefsStore(): Store<AppPrefsSchema> {
33+
if (!prefsStore) {
34+
prefsStore = new Store<AppPrefsSchema>({
35+
name: 'app-prefs',
36+
defaults: { hasShownTrayHint: false },
37+
clearInvalidConfig: true,
38+
})
39+
}
40+
return prefsStore
41+
}
3242

3343
function getIcons(): { normal: NativeImage; unread: NativeImage } {
3444
if (!normalIcon) normalIcon = nativeImage.createFromDataURL(TRAY_ICONS[iconEnv].normal)
@@ -118,17 +128,19 @@ export function updateTrayUnread(count: number): void {
118128
*/
119129
export function maybeShowTrayHint(): void {
120130
// A best-effort one-time hint must never bubble out of the window 'close'
121-
// handler — guard every electron-store read/write (e.g. an unreadable file).
131+
// handler — guard store construction and every read/write (e.g. an unreadable
132+
// prefs file or a path that is a directory).
122133
try {
123-
if (prefsStore.get('hasShownTrayHint')) return
134+
const store = getPrefsStore()
135+
if (store.get('hasShownTrayHint')) return
124136
if (!Notification.isSupported()) return
125137

126138
new Notification({
127139
title: 'LAPLACE Comet',
128140
body: 'LAPLACE Comet 仍在后台运行,可从系统托盘重新打开。',
129141
}).show()
130142

131-
prefsStore.set('hasShownTrayHint', true)
143+
store.set('hasShownTrayHint', true)
132144
} catch (err) {
133145
console.error('[Tray] tray hint failed (non-fatal):', err)
134146
}

0 commit comments

Comments
 (0)