From be19e60a1bf5d358d996520a23bf3d07706d2d34 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sat, 11 Jul 2026 14:32:42 +0200 Subject: [PATCH] Email-Anhang: echte IMAP-Fehlermeldung durchreichen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- backend/src/controllers/cachedEmail.controller.ts | 11 ++++++++++- backend/src/services/imapService.ts | 11 +++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/backend/src/controllers/cachedEmail.controller.ts b/backend/src/controllers/cachedEmail.controller.ts index fb9e18df..025a9504 100644 --- a/backend/src/controllers/cachedEmail.controller.ts +++ b/backend/src/controllers/cachedEmail.controller.ts @@ -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({ diff --git a/backend/src/services/imapService.ts b/backend/src/services/imapService.ts index 3bb5afbe..d35a3fe1 100644 --- a/backend/src/services/imapService.ts +++ b/backend/src/services/imapService.ts @@ -530,9 +530,16 @@ async function fetchAttachmentInner( } } } catch (fetchErr) { - console.error(`[fetchAttachment] fetch(UID ${uid}) failed:`, fetchErr); + // imapflow wirft bei IMAP-NO/BAD immer nur `new Error('Command failed')`, + // die eigentliche Server-Antwort steht in `.responseText`. Ohne die + // Anreicherung sähe der User oben im UI nur "Command failed" ohne + // Kontext (Ursache 2026-07-11). + const anyErr = fetchErr as { message?: string; responseText?: string; responseStatus?: string; response?: unknown }; + const detail = anyErr?.responseText || anyErr?.message || 'unbekannter Fehler'; + const statusTag = anyErr?.responseStatus ? `${anyErr.responseStatus} ` : ''; + console.error(`[fetchAttachment] fetch(UID ${uid}) failed [${statusTag}${detail}]:`, fetchErr); throw new Error( - `Nachricht mit UID ${uid} konnte nicht geladen werden (${fetchErr instanceof Error ? fetchErr.message : 'unbekannter Fehler'}). Möglicherweise wurde sie im IMAP-Postfach verschoben oder gelöscht.`, + `Nachricht mit UID ${uid} konnte nicht geladen werden: ${statusTag}${detail}. Möglicherweise wurde sie im IMAP-Postfach verschoben oder gelöscht.`, ); }