fix: SMTP-Fehler nur bei Empfaengerablehnung endgueltig
Bisher setzte jeder SMTP-5xx die Mail sofort auf FAILED, auch Anmelde- und Richtlinienfehler (EAUTH, EMESSAGE, 552). Ein kaputtes SMTP-Secret haette alle Buchungs- und Zahlungsmails verworfen, ohne Rueckweg (dedupeKey verhindert erneutes Einreihen). Endgueltig ist jetzt nur EENVELOPE mit 550, 551, 553, 556 oder 5xx mit Status 5.1.x. Alles andere bleibt PENDING und wird bis MAX_EMAIL_ATTEMPTS wiederholt. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
e6fa383934
commit
34ccbc3b9a
2 files changed
+48
-7
No files matched your search
+12
-5
@@ -85,14 +85,21 @@ async function deliver(message: { id: string; toAddress: string; subject: string
|
||||
});
|
||||
}
|
||||
|
||||
const RECIPIENT_REJECTION_CODES = new Set([550, 551, 553, 556]);
|
||||
|
||||
/**
|
||||
* SMTP-Antworten 5xx sind endgueltig (z. B. Empfaenger abgelehnt, Domain ohne
|
||||
* Mailserver): erneutes Senden aendert nichts und liesse jeden Worker-Lauf
|
||||
* scheitern. 4xx und Verbindungsfehler bleiben wiederholbar.
|
||||
* Endgueltig ist nur eine Ablehnung des Empfaengers (nodemailer EENVELOPE, RCPT TO):
|
||||
* 550/551/553/556 oder 5xx mit Status 5.1.x (Adresse/Domain falsch). Alles andere
|
||||
* (Anmeldung EAUTH, Richtlinie/Blocklist EMESSAGE, 552, 4xx, Verbindung) liegt am
|
||||
* Server oder Absender; die Mail bleibt PENDING und wird bis MAX_EMAIL_ATTEMPTS
|
||||
* wiederholt, damit ein kaputtes SMTP-Secret keine Mails endgueltig verwirft.
|
||||
*/
|
||||
export function isPermanentMailError(error: unknown): boolean {
|
||||
const code = typeof error === "object" && error !== null ? (error as { responseCode?: unknown }).responseCode : undefined;
|
||||
return typeof code === "number" && code >= 500 && code < 600;
|
||||
if (typeof error !== "object" || error === null) return false;
|
||||
const { code, responseCode, response } = error as { code?: unknown; responseCode?: unknown; response?: unknown };
|
||||
if (code !== "EENVELOPE" || typeof responseCode !== "number") return false;
|
||||
if (RECIPIENT_REJECTION_CODES.has(responseCode)) return true;
|
||||
return responseCode >= 500 && responseCode < 600 && typeof response === "string" && /(^|\s)5\.1\.\d+(\s|$)/.test(response);
|
||||
}
|
||||
|
||||
/** SMTP-Fehlermeldungen nennen den Empfaenger; ins Log und in lastError kommt er nicht. */
|
||||
|
||||
Reference in new issue
Block a user