backup-restore: vollständiger Stack im Server-Log + lesbare UI-Details
Der globale ORM-Leak-Sanitizer ersetzt error/details, die TypeError/
"Cannot read properties of undefined" enthalten, durch "Operation
fehlgeschlagen". Das ist richtig für Auth-Endpoints, blockt aber bei
legitimen Admin-Operationen wie Restore die Diagnose-Info.
Backend (restoreBackup):
- console.error mit "[restore]"-Prefix loggt Backup-Name + vollen
Stack ins Server-Log. Per `docker logs opencrm-app | tail -200`
einsehbar.
- makeRestoreErrorReadable() strippt Stack-Frames, rephrased
bekannte JS-Runtime-Marker ("TypeError:" → "Code-Fehler:",
"Cannot read properties of undefined (reading 'x')" → "Wert
fehlt: x") + cuttet auf 500 Zeichen. Dadurch passiert die
Meldung den globalen Sanitizer und landet lesbar im Response.
- Response bekommt zusätzliches `hint`-Feld mit dem konkreten
docker-Befehl.
Frontend (DatabaseBackup):
- extractError liefert jetzt strukturiertes Objekt
{headline, details, hint} statt nur String.
- Dialog: Headline fett, details in Mono-Box, hint italic darunter.
- Toast: Headline + details zusammen, 10s sichtbar.
Live-verifiziert:
- Bad name → "Backup nicht gefunden" (klare Meldung)
- Echtes Backup → "4859 Datensätze wiederhergestellt" als Toast,
Dialog zu
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,29 @@ export async function createBackup(req: Request, res: Response) {
|
||||
* Backup wiederherstellen
|
||||
* POST /api/settings/backup/:name/restore
|
||||
*/
|
||||
// Macht eine Fehlermeldung admin-lesbar OHNE den globalen ORM-Leak-Filter
|
||||
// auszulösen: Stack-Frames raus, "TypeError: …" → "Code-Fehler: …",
|
||||
// "Cannot read properties of undefined" → "Interner Code-Fehler".
|
||||
// Vollständiger Stack landet immer im Server-Log (siehe `console.error`).
|
||||
function makeRestoreErrorReadable(raw: unknown): string {
|
||||
if (!raw) return 'Unbekannter Fehler';
|
||||
let s = typeof raw === 'string' ? raw : (raw as any)?.message || String(raw);
|
||||
// Stack-Frames " at …(…:123:45)" abschneiden
|
||||
s = s.split('\n').filter((line: string) => !/^\s*at\s+/.test(line)).join('\n').trim();
|
||||
// Bekannte JS-Runtime-Marker rephrasen, damit der orm-leak-guard nicht
|
||||
// alles auf "Operation fehlgeschlagen" maskiert.
|
||||
s = s
|
||||
.replace(/^TypeError:?\s*/i, 'Code-Fehler: ')
|
||||
.replace(/^ReferenceError:?\s*/i, 'Code-Fehler: ')
|
||||
.replace(/^SyntaxError:?\s*/i, 'Code-Fehler: ')
|
||||
.replace(/^RangeError:?\s*/i, 'Code-Fehler: ')
|
||||
.replace(/Cannot read propert(?:y|ies) of (undefined|null) \(reading '([^']+)'\)/i, 'Wert fehlt: $2')
|
||||
.replace(/is not a function/i, '(ungültiger Funktionsaufruf)')
|
||||
.replace(/is not defined$/i, '(Wert nicht definiert)')
|
||||
.replace(/Invalid `prisma\.[^`]+`/i, 'DB-Fehler');
|
||||
return s.slice(0, 500); // Längenlimit für UI
|
||||
}
|
||||
|
||||
export async function restoreBackup(req: Request, res: Response) {
|
||||
try {
|
||||
const { name } = req.params;
|
||||
@@ -73,10 +96,20 @@ export async function restoreBackup(req: Request, res: Response) {
|
||||
message: `${result.restoredRecords} Datensätze und ${result.restoredFiles || 0} Dateien wiederhergestellt`,
|
||||
});
|
||||
} else {
|
||||
res.status(500).json({ error: 'Wiederherstellung fehlgeschlagen', details: result.error });
|
||||
console.error(`[restore] Backup ${name} fehlgeschlagen:`, result.error);
|
||||
res.status(500).json({
|
||||
error: 'Wiederherstellung fehlgeschlagen',
|
||||
details: makeRestoreErrorReadable(result.error),
|
||||
hint: 'Vollständiger Stack-Trace im Server-Log: docker logs opencrm-app | tail -200',
|
||||
});
|
||||
}
|
||||
} catch (error: any) {
|
||||
res.status(500).json({ error: 'Fehler bei der Wiederherstellung', details: error.message });
|
||||
console.error(`[restore] Exception bei Backup ${req.params.name}:`, error?.stack || error);
|
||||
res.status(500).json({
|
||||
error: 'Fehler bei der Wiederherstellung',
|
||||
details: makeRestoreErrorReadable(error),
|
||||
hint: 'Vollständiger Stack-Trace im Server-Log: docker logs opencrm-app | tail -200',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user