fix(email): surface the real error on test/save/flush instead of generic toast

The test-email, save-config, and flush mutations all showed the generic
'Failed to save changes' toast on error, hiding the actual backend reason —
so a failing test email looked like a save failure and gave no diagnosis.
Show response.data.error / .details (SMTP auth/connection failure, masked
password, private-host rejection, …) with the generic string as fallback.
This commit is contained in:
Luca
2026-06-03 19:56:26 +02:00
parent 68c967f9bb
commit 47edbf64b5
+15 -6
View File
@@ -228,14 +228,23 @@ export const EmailConfigPage: React.FC = () => {
}, [selectedTemplate]); }, [selectedTemplate]);
// Mutations // Mutations
// Surface the actual backend error (SMTP auth/connection failure, masked
// password, private-host rejection, …) instead of a generic toast — for
// email config these messages are the whole diagnosis.
const errMsg = (e: any, fallback: string): string =>
e?.response?.data?.error
|| e?.response?.data?.details
|| e?.message
|| fallback;
const saveConfigMutation = useMutation({ const saveConfigMutation = useMutation({
mutationFn: (config: EmailConfig) => emailService.updateConfig(config), mutationFn: (config: EmailConfig) => emailService.updateConfig(config),
onSuccess: () => { onSuccess: () => {
toast.success(t('toast.emailConfigSaved')); toast.success(t('toast.emailConfigSaved'));
queryClient.invalidateQueries({ queryKey: ['email-config'] }); queryClient.invalidateQueries({ queryKey: ['email-config'] });
}, },
onError: () => { onError: (e: any) => {
toast.error(t('toast.saveError')); toast.error(errMsg(e, t('toast.saveError')));
} }
}); });
@@ -244,8 +253,8 @@ export const EmailConfigPage: React.FC = () => {
onSuccess: () => { onSuccess: () => {
toast.success(t('email.testEmailSuccess')); toast.success(t('email.testEmailSuccess'));
}, },
onError: () => { onError: (e: any) => {
toast.error(t('toast.saveError')); toast.error(errMsg(e, t('toast.saveError')));
} }
}); });
@@ -258,8 +267,8 @@ export const EmailConfigPage: React.FC = () => {
toast.success(t('email.flushQueue.success', { sent: summary.sent, failed: summary.failed })); toast.success(t('email.flushQueue.success', { sent: summary.sent, failed: summary.failed }));
} }
}, },
onError: () => { onError: (e: any) => {
toast.error(t('toast.saveError')); toast.error(errMsg(e, t('toast.saveError')));
} }
}); });