Skip to content

Commit 4c7bd55

Browse files
fix(stage-tamagotchi): make handleAppExit more robust (#1321)
* fix(stage-tamagotchi): make handleAppExit more robust * chore: code style update * chore: code style update --------- Co-authored-by: Garfield Lee <Garfield550@users.noreply.github.com>
1 parent c897aad commit 4c7bd55

1 file changed

Lines changed: 32 additions & 7 deletions

File tree

apps/stage-tamagotchi/src/main/index.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,17 @@ electronApp.setAppUserModelId('ai.moeru.airi')
8383
initScreenCaptureForMain()
8484

8585
let fileLogger: FileLoggerHandle = nullFileLoggerHandle
86+
let skipFileLogging = false
8687

8788
app.whenReady().then(async () => {
8889
// Initialize file logger and register the hook
8990
fileLogger = await setupFileLogger()
9091

9192
// Register the global hook for file logging
9293
setGlobalHookPostLog((_, formatted) => {
93-
if (fileLogger.logFileFd !== null) {
94-
void fileLogger.appendLog(formatted)
95-
}
94+
if (skipFileLogging || fileLogger.logFileFd === null)
95+
return
96+
void fileLogger.appendLog(formatted)
9697
})
9798

9899
injeca.setLogger(createLoggLogger(useLogg('injeca').useGlobalConfig()))
@@ -211,13 +212,37 @@ async function handleAppExit() {
211212

212213
appExiting = true
213214

215+
let exitedNormally = true
216+
217+
/**
218+
* Safely execute fn and log any errors that occur, marking the exit as abnormal
219+
* if an error is caught.
220+
*
221+
* @param operation - A verb phrase describing the operation.
222+
* @param fn - Any function to execute. It can be either sync or async.
223+
* @returns A promise that resolves when the operation is complete.
224+
*/
225+
async function logIfError(operation: string, fn: () => unknown): Promise<void> {
226+
try {
227+
await fn()
228+
}
229+
catch (error) {
230+
exitedNormally = false
231+
log.withError(error).error(`[app-exit] Failed to ${operation}:`)
232+
}
233+
}
234+
214235
await Promise.all([
215-
emitAppBeforeQuit(),
216-
injeca.stop(),
217-
fileLogger.close(), // Ensure all logs are flushed
236+
logIfError('execute onAppBeforeQuit hooks', () => emitAppBeforeQuit()),
237+
logIfError('stop injeca', () => injeca.stop()),
218238
])
219239

220-
app.exit(0)
240+
// Prevent the global log hook from trying to write to the file after close() is called,
241+
// which would cause a recursive failure if close() itself throws.
242+
skipFileLogging = true
243+
await logIfError('flush file logs', () => fileLogger.close()) // Ensure all logs are flushed
244+
245+
app.exit(exitedNormally ? 0 : 1)
221246
}
222247

223248
process.on('SIGINT', () => handleAppExit())

0 commit comments

Comments
 (0)