Skip to content

Commit d408bb4

Browse files
staticoclaude
andcommitted
Fix logger not capturing crash logs
The logging system was losing logs during crashes because: 1. Async writes via queueMicrotask weren't completing before process exit 2. uncaughtException/unhandledRejection handlers didn't flush logs 3. No exit handler to catch all exit paths Changes: - Add flushSync() method for synchronous writes - Make Logger.shutdown() flush synchronously - Call Logger.shutdown() in crash handlers (uncaughtException, unhandledRejection) - Add process.on("exit") as final safety net Now all logs are guaranteed to be written before the process exits, making crash debugging actually possible. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 2b21096 commit d408bb4

2 files changed

Lines changed: 28 additions & 8 deletions

File tree

src/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,19 @@ truncateLogIfNeeded();
5252

5353
process.on("uncaughtException", (error) => {
5454
logError("UNCAUGHT EXCEPTION", error);
55+
Logger.error("Process", "Uncaught exception", error);
56+
Logger.shutdown();
5557
console.error("Fatal error:", error.message);
5658
console.error(`Stack trace saved to ${ERROR_LOG_PATH}`);
5759
process.exit(1);
5860
});
5961

6062
process.on("unhandledRejection", (reason) => {
6163
logError("UNHANDLED REJECTION", reason);
64+
Logger.error("Process", "Unhandled rejection", reason instanceof Error ? reason : undefined, {
65+
reason: String(reason)
66+
});
67+
Logger.shutdown();
6268
console.error("Unhandled promise rejection:", reason);
6369
process.exit(1);
6470
});
@@ -81,6 +87,11 @@ process.on("SIGHUP", () => {
8187
process.exit(0);
8288
});
8389

90+
// Final safety net - flush logs on any exit
91+
process.on("exit", (code) => {
92+
Logger.shutdown();
93+
});
94+
8495
// Parse CLI arguments
8596
const args = process.argv.slice(2);
8697
let address = "192.168.0.123";

src/logger.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,12 @@ class Logger {
5656
static shutdown(): void {
5757
if (Logger.instance) {
5858
Logger.instance.stopFlushTimer();
59-
Logger.instance.flushNow();
59+
// Flush synchronously to ensure logs are written before exit
60+
if (Logger.instance.writeQueue.length > 0) {
61+
const entries = Logger.instance.writeQueue.join("");
62+
Logger.instance.writeQueue = [];
63+
Logger.instance.flushSync(entries);
64+
}
6065
Logger.instance = null;
6166
}
6267
}
@@ -102,16 +107,20 @@ class Logger {
102107
this.writeQueue = [];
103108

104109
queueMicrotask(() => {
105-
try {
106-
appendFileSync(LOG_PATH, entries);
107-
this.rotateLogIfNeeded();
108-
} catch (error) {
109-
// Can't log errors in the logger, just output to console
110-
console.error("Failed to write log:", error);
111-
}
110+
this.flushSync(entries);
112111
});
113112
}
114113

114+
private flushSync(entries: string): void {
115+
try {
116+
appendFileSync(LOG_PATH, entries);
117+
this.rotateLogIfNeeded();
118+
} catch (error) {
119+
// Can't log errors in the logger, just output to console
120+
console.error("Failed to write log:", error);
121+
}
122+
}
123+
115124
private rotateLogIfNeeded(): void {
116125
try {
117126
if (!existsSync(LOG_PATH)) return;

0 commit comments

Comments
 (0)