Toast-Benachrichtigungen bei IMAP-Sync- und SMTP-Send-Fehlern
Bisher blieb ein fehlgeschlagener IMAP-Sync oder E-Mail-Versand still – der User sah nur im Browser-Devtools, dass etwas schief lief. Jetzt erscheint eine rote Toast-Benachrichtigung (8 Sekunden) mit der konkreten Fehlermeldung des Servers, z.B. 'Sync fehlgeschlagen: IMAP-Authentifizierung fehlgeschlagen: NO [AUTHENTICATIONFAILED]'. EmailClientTab (Synchronisieren-Button): - toast.success bei erfolgreichem Sync - toast.error bei Fehler + bei Backend-Response mit success=false ComposeEmailModal (Senden): - toast.success bei erfolgreichem Versand - toast.error bei SMTP-Fehler mit Server-Response (zusätzlich zum Inline-Fehler) Außerdem im imapService.testImapConnection: - Roh-Error wird jetzt geloggt (code, response, responseStatus, authenticationFailed) - ImapFlow-spezifische Felder werden in die Fehlermeldung übernommen, sodass z.B. '2 NO [AUTHENTICATIONFAILED] Authentication failed.' direkt sichtbar wird Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
620bc1bcd9
commit
cfcdf088df
|
|
@ -297,9 +297,36 @@ export async function testImapConnection(credentials: ImapCredentials): Promise<
|
|||
// Ignorieren
|
||||
}
|
||||
|
||||
// Rohes Error-Objekt loggen, damit wir ImapFlow-spezifische Felder sehen
|
||||
console.error('[testImapConnection] Raw error:', error);
|
||||
if (error && typeof error === 'object') {
|
||||
const e = error as any;
|
||||
console.error('[testImapConnection] Details:', {
|
||||
code: e.code,
|
||||
response: e.response,
|
||||
responseStatus: e.responseStatus,
|
||||
responseText: e.responseText,
|
||||
authenticationFailed: e.authenticationFailed,
|
||||
serverResponseCode: e.serverResponseCode,
|
||||
});
|
||||
}
|
||||
|
||||
if (error instanceof Error) {
|
||||
const msg = error.message.toLowerCase();
|
||||
const errorCode = (error as NodeJS.ErrnoException).code?.toLowerCase() || '';
|
||||
const e = error as any;
|
||||
|
||||
// ImapFlow-spezifische Details durchreichen wenn vorhanden
|
||||
if (e.authenticationFailed) {
|
||||
throw new Error(
|
||||
`IMAP-Authentifizierung fehlgeschlagen${e.response ? `: ${e.response}` : ''}`,
|
||||
);
|
||||
}
|
||||
if (e.response || e.responseText) {
|
||||
throw new Error(
|
||||
`IMAP ${e.responseStatus || 'Fehler'}: ${e.response || e.responseText}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (msg.includes('authentication') || msg.includes('login')) {
|
||||
throw new Error('IMAP-Authentifizierung fehlgeschlagen');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useState, useRef, useEffect } from 'react';
|
||||
import { Send, Paperclip, X, FileText } from 'lucide-react';
|
||||
import toast from 'react-hot-toast';
|
||||
import Modal from '../ui/Modal';
|
||||
import Button from '../ui/Button';
|
||||
import { stressfreiEmailApi, CachedEmail, MailboxAccount, EmailAttachment } from '../../services/api';
|
||||
|
|
@ -150,12 +151,24 @@ export default function ComposeEmailModal({
|
|||
attachments: attachments.length > 0 ? attachments : undefined,
|
||||
contractId,
|
||||
}),
|
||||
onSuccess: () => {
|
||||
onSuccess: (result) => {
|
||||
// Backend kann success=false zurückgeben auch bei HTTP 200
|
||||
if (result && (result as any).success === false) {
|
||||
const msg = (result as any).error || 'E-Mail-Versand fehlgeschlagen';
|
||||
setError(msg);
|
||||
toast.error(`SMTP-Fehler: ${msg}`, { duration: 8000 });
|
||||
return;
|
||||
}
|
||||
toast.success('E-Mail versendet');
|
||||
onSuccess?.();
|
||||
handleClose();
|
||||
},
|
||||
onError: (err) => {
|
||||
setError(err instanceof Error ? err.message : 'Fehler beim Senden');
|
||||
onError: (err: any) => {
|
||||
const msg =
|
||||
err?.response?.data?.error ||
|
||||
(err instanceof Error ? err.message : 'Fehler beim Senden');
|
||||
setError(msg);
|
||||
toast.error(`SMTP-Fehler: ${msg}`, { duration: 8000 });
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import { RefreshCw, Plus, Mail, Inbox, Send, Trash2 } from 'lucide-react';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import toast from 'react-hot-toast';
|
||||
import { cachedEmailApi, stressfreiEmailApi, CachedEmail } from '../../services/api';
|
||||
import { useAuth } from '../../context/AuthContext';
|
||||
import Button from '../ui/Button';
|
||||
|
|
@ -95,7 +96,14 @@ export default function EmailClientTab({ customerId }: EmailClientTabProps) {
|
|||
// Synchronisation
|
||||
const syncMutation = useMutation({
|
||||
mutationFn: (accountId: number) => stressfreiEmailApi.syncEmails(accountId),
|
||||
onSuccess: () => {
|
||||
onSuccess: (result) => {
|
||||
// Backend liefert success=false bei IMAP-Fehler, aber ohne HTTP-Error
|
||||
if (result && (result as any).success === false) {
|
||||
const err = (result as any).error || 'IMAP-Synchronisation fehlgeschlagen';
|
||||
toast.error(`Sync fehlgeschlagen: ${err}`, { duration: 8000 });
|
||||
return;
|
||||
}
|
||||
toast.success('E-Mails synchronisiert');
|
||||
// E-Mail-Listen neu laden
|
||||
queryClient.invalidateQueries({ queryKey: ['emails'] });
|
||||
// Ordner-Anzahlen aktualisieren
|
||||
|
|
@ -103,6 +111,10 @@ export default function EmailClientTab({ customerId }: EmailClientTabProps) {
|
|||
// Mailbox-Accounts aktualisieren
|
||||
queryClient.invalidateQueries({ queryKey: ['mailbox-accounts', customerId] });
|
||||
},
|
||||
onError: (error: any) => {
|
||||
const msg = error?.response?.data?.error || error?.message || 'Unbekannter Fehler';
|
||||
toast.error(`Sync fehlgeschlagen: ${msg}`, { duration: 8000 });
|
||||
},
|
||||
});
|
||||
|
||||
const handleSync = () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue