Email-Anhang: echte IMAP-Fehlermeldung durchreichen

Bug: Anhang-Download schlug mit "Fehler beim Herunterladen des
Anhangs: Command failed" fehl – ohne jeden Kontext, warum.

Ursache: imapflow wirft bei jedem IMAP-NO/BAD-Response nur
`new Error('Command failed')` und legt den echten Server-Grund
in `.responseText` / `.responseStatus` ab. Unser Code las nur
`.message` und verlor damit alle Information.

Fix:
- fetchAttachmentInner extrahiert responseText/responseStatus
  aus dem imapflow-Error und packt sie in die geworfene Meldung.
- downloadAttachment-Catch macht das gleiche, damit auch andere
  IMAP-Fehler (mailboxOpen, connect) mit sinnvollem Text
  durchkommen.
- Zusätzlicher Friendly-Mapping-Fall für "no longer exist" /
  "no such message" → klare Meldung, dass die E-Mail-Liste
  neu synchronisiert werden sollte.

Damit sieht der User im UI jetzt z.B. "NO Some of the requested
messages no longer exist" statt "Command failed" und weiß, dass
ein Resync hilft.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 14:32:42 +02:00
co-authored by Claude Opus 4.7
parent 96f8715e13
commit be19e60a1b
2 changed files with 19 additions and 3 deletions
@@ -797,7 +797,14 @@ export async function downloadAttachment(req: AuthRequest, res: Response): Promi
res.send(attachment.content);
} catch (error) {
console.error('downloadAttachment error:', error);
const rawMsg = error instanceof Error ? error.message : 'Unbekannter Fehler';
// imapflow versteckt die eigentliche Server-Antwort in
// `.responseText`/`.responseStatus` und setzt `.message` immer nur auf
// `'Command failed'`. Wenn wir nur die `.message` ausgeben, sieht der
// Endnutzer im UI nichts Verwertbares.
const anyErr = error as { message?: string; responseText?: string; responseStatus?: string };
const rawMsg = anyErr?.responseText
? `${anyErr.responseStatus ? anyErr.responseStatus + ' ' : ''}${anyErr.responseText}`
: error instanceof Error ? error.message : 'Unbekannter Fehler';
const lower = rawMsg.toLowerCase();
let friendly = rawMsg;
@@ -810,6 +817,8 @@ export async function downloadAttachment(req: AuthRequest, res: Response): Promi
friendly = 'Zeitüberschreitung beim Verbinden zum IMAP-Server. Bitte später erneut versuchen.';
} else if (lower.includes('authentication') || lower.includes('auth')) {
friendly = 'IMAP-Authentifizierung fehlgeschlagen. Bitte Zugangsdaten prüfen.';
} else if (lower.includes('no longer exist') || lower.includes('no such message') || lower.includes('unknown')) {
friendly = 'Nachricht existiert im IMAP-Postfach nicht mehr (wahrscheinlich verschoben oder gelöscht). Bitte E-Mail-Liste neu synchronisieren.';
}
res.status(500).json({