fix: backup — error-Events auf spawn abfangen, Tilde in Key-Pfad expandieren

Ohne 'error'-Handler auf den Child-Prozessen führt spawn ENOENT zu
uncaughtException statt zu einem gefangenen Promise-Reject. Außerdem
wird '~' im BACKUP_SSH_KEY_PATH jetzt manuell zu $HOME expandiert,
da spawn keine Shell-Expansion macht.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 15:29:38 +02:00
parent cf95f3027f
commit 10b52d268e
+9 -1
View File
@@ -14,7 +14,10 @@ async function runBackup(): Promise<void> {
return;
}
const [, sshHost, remotePath] = match;
const keyPath = process.env.BACKUP_SSH_KEY_PATH || '/app/.ssh/id_rsa';
const rawKeyPath = process.env.BACKUP_SSH_KEY_PATH || '/app/.ssh/id_rsa';
const keyPath = rawKeyPath.startsWith('~')
? rawKeyPath.replace('~', process.env.HOME || '/root')
: rawKeyPath;
const ts = new Date().toISOString().replace('T', '_').replace(/:/g, '-').slice(0, 19);
const filename = `sternwarte_${ts}.sql.gz`;
@@ -48,6 +51,10 @@ async function runBackup(): Promise<void> {
dump.stderr.on('data', (d: Buffer) => { dumpErr += d.toString(); });
ssh.stderr.on('data', (d: Buffer) => { sshErr += d.toString(); });
dump.on('error', reject);
gzip.on('error', reject);
ssh.on('error', reject);
dump.on('close', (code) => { if (code !== 0) gzip.stdin.end(); });
gzip.on('close', () => ssh.stdin.end());
@@ -66,6 +73,7 @@ async function runBackup(): Promise<void> {
...sshOpts, sshHost,
`find ${remotePath} -name 'sternwarte_*.sql.gz' -mtime +30 -delete`,
]);
ssh.on('error', (e) => { console.error('[backup] Cleanup spawn-Fehler:', e.message); resolve(); });
ssh.on('close', (code) => {
if (code !== 0) console.error('[backup] Cleanup fehlgeschlagen (exit ' + code + ')');
resolve();