fix: memory leaks and error handling improvements

- execution-bridge: track and cleanup retry timers to prevent memory leaks
- model-selector: add exhaustive type check for ModelTier
- ralph-tracker: fix division by zero when summary.total is 0
- respawn-controller: remove event listeners on stop to prevent memory leaks
- screen-manager: use Promise.allSettled for better error handling in stats
- session-manager: use Promise.allSettled for stopAllSessions resilience

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
arkon
2026-01-28 20:19:14 +01:00
co-authored by Claude Opus 4.5
parent e0a695fed7
commit 8fb8e6fa83
6 changed files with 55 additions and 10 deletions
+9 -4
View File
@@ -717,10 +717,10 @@ export class ScreenManager extends EventEmitter {
} catch {
// Fall back to individual queries if batch fails
const statsPromises = screens.map(screen => this.getProcessStats(screen.sessionId));
const allStats = await Promise.all(statsPromises);
const results = await Promise.allSettled(statsPromises);
return screens.map((screen, i) => ({
...screen,
stats: allStats[i] || undefined
stats: results[i].status === 'fulfilled' ? (results[i].value ?? undefined) : undefined
}));
}
@@ -738,8 +738,13 @@ export class ScreenManager extends EventEmitter {
}
this.statsInterval = setInterval(async () => {
const screensWithStats = await this.getScreensWithStats();
this.emit('statsUpdated', screensWithStats);
try {
const screensWithStats = await this.getScreensWithStats();
this.emit('statsUpdated', screensWithStats);
} catch (err) {
// Log but don't crash - stats collection is non-critical
console.error('[ScreenManager] Stats collection error:', err);
}
}, intervalMs);
}