fix(error): add global error handler, fix stores and dispatcher

- Global unhandledrejection handler with IPC+network filtering
- Agent dispatcher heartbeat uses handleInfraError (was fire-and-forget)
- All stores: layout, workspace, anchors, theme, plugins, machines,
  wake-scheduler — silent failures replaced with handleInfraError
- initGlobalErrorHandler() called in App.svelte onMount
This commit is contained in:
Hibryda 2026-03-18 01:22:12 +01:00
parent 8b3b0ab720
commit 93b3db8b1f
10 changed files with 73 additions and 35 deletions

View file

@ -9,6 +9,7 @@ import {
updateSessionGroup,
type PersistedSession,
} from '../adapters/session-bridge';
import { handleInfraError } from '../utils/handle-error';
export type LayoutPreset = '1-col' | '2-col' | '3-col' | '2x2' | 'master-stack';
@ -46,14 +47,14 @@ function persistSession(pane: Pane): void {
created_at: now,
last_used_at: now,
};
saveSession(session).catch(e => console.warn('Failed to persist session:', e));
saveSession(session).catch(e => handleInfraError(e, 'layout.persistSession'));
}
function persistLayout(): void {
saveLayout({
preset: activePreset,
pane_ids: panes.map(p => p.id),
}).catch(e => console.warn('Failed to persist layout:', e));
}).catch(e => handleInfraError(e, 'layout.persistLayout'));
}
// --- Public API ---
@ -84,14 +85,14 @@ export function removePane(id: string): void {
focusedPaneId = panes.length > 0 ? panes[0].id : null;
}
autoPreset();
deleteSession(id).catch(e => console.warn('Failed to delete session:', e));
deleteSession(id).catch(e => handleInfraError(e, 'layout.deleteSession'));
persistLayout();
}
export function focusPane(id: string): void {
focusedPaneId = id;
panes = panes.map(p => ({ ...p, focused: p.id === id }));
touchSession(id).catch(e => console.warn('Failed to touch session:', e));
touchSession(id).catch(e => handleInfraError(e, 'layout.touchSession'));
}
export function focusPaneByIndex(index: number): void {
@ -109,7 +110,7 @@ export function renamePaneTitle(id: string, title: string): void {
const pane = panes.find(p => p.id === id);
if (pane) {
pane.title = title;
updateSessionTitle(id, title).catch(e => console.warn('Failed to update title:', e));
updateSessionTitle(id, title).catch(e => handleInfraError(e, 'layout.updateTitle'));
}
}
@ -117,7 +118,7 @@ export function setPaneGroup(id: string, group: string): void {
const pane = panes.find(p => p.id === id);
if (pane) {
pane.group = group || undefined;
updateSessionGroup(id, group).catch(e => console.warn('Failed to update group:', e));
updateSessionGroup(id, group).catch(e => handleInfraError(e, 'layout.updateGroup'));
}
}
@ -156,7 +157,7 @@ export async function restoreFromDb(): Promise<void> {
focusPane(panes[0].id);
}
} catch (e) {
console.warn('Failed to restore sessions from DB:', e);
handleInfraError(e, 'layout.restoreFromDb');
}
}