- Electron crash handlers (render-process-gone, child-process-gone, unresponsive/responsive, process warnings) with a circuit-breaker auto-reload for renderer crashes - Renderer error capture (window.onerror, unhandledrejection, React ErrorBoundary) forwarded to the main log via a one-way IPC channel - Memory-pressure heartbeat measured against the V8 heap_size_limit - Gated DEBUG log level (RD_DEBUG) and an in-memory ring of recent WARN/ERROR lines, exposed via the /errors endpoint and support bundle - Disk-error classification (ENOSPC etc.) on download failures and integrity-check pass/fail logging
57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
// Maps low-level filesystem/OS error codes to a human-readable cause so that a
|
|
// generic "write failed" or "timeout" can be reported as the specific root cause
|
|
// (disk full, permission denied, ...). Pure + side-effect-free for testing.
|
|
|
|
const DISK_ERROR_REASONS: Record<string, string> = {
|
|
ENOSPC: "Festplatte voll (ENOSPC)",
|
|
EDQUOT: "Speicher-Kontingent erschöpft (EDQUOT)",
|
|
EROFS: "Laufwerk schreibgeschützt (EROFS)",
|
|
EACCES: "Zugriff verweigert (EACCES)",
|
|
EPERM: "Operation nicht erlaubt (EPERM)",
|
|
EMFILE: "Zu viele offene Dateien (EMFILE)",
|
|
ENFILE: "System-Limit offener Dateien erreicht (ENFILE)",
|
|
EBUSY: "Datei/Laufwerk belegt (EBUSY)",
|
|
ENODEV: "Gerät nicht vorhanden (ENODEV)",
|
|
ENXIO: "Gerät getrennt (ENXIO)",
|
|
EIO: "Ein-/Ausgabefehler des Datenträgers (EIO)"
|
|
};
|
|
|
|
export function classifyDiskError(err: unknown): string | null {
|
|
const code = extractErrorCode(err);
|
|
if (code && DISK_ERROR_REASONS[code]) {
|
|
return DISK_ERROR_REASONS[code];
|
|
}
|
|
// Some errors arrive as plain strings/messages without a `.code`; fall back to
|
|
// scanning the text for a known code token.
|
|
const text = errorText(err);
|
|
for (const knownCode of Object.keys(DISK_ERROR_REASONS)) {
|
|
if (text.includes(knownCode)) {
|
|
return DISK_ERROR_REASONS[knownCode];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function extractErrorCode(err: unknown): string {
|
|
if (err && typeof err === "object") {
|
|
const code = (err as { code?: unknown }).code;
|
|
if (typeof code === "string") {
|
|
return code.toUpperCase();
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function errorText(err: unknown): string {
|
|
if (typeof err === "string") {
|
|
return err;
|
|
}
|
|
if (err && typeof err === "object") {
|
|
const message = (err as { message?: unknown }).message;
|
|
if (typeof message === "string") {
|
|
return message;
|
|
}
|
|
}
|
|
return String(err ?? "");
|
|
}
|