From 3f01358f9d45f3e803884e970d60d6943536add0 Mon Sep 17 00:00:00 2001 From: Aman Ganapathy <84686202+nams1570@users.noreply.github.com> Date: Tue, 7 Apr 2026 09:20:39 -0700 Subject: [PATCH] [Refactor] Make all SMTP 4yz Errors Retryable (#1293) ### Context The `emails-low-level.tsx` file is where the sending logic of an email over smtp occurs. It tries to send an email, and if there is an issue it has logic to mark the email as retryable or not. Then, the `email-queue-step` itself handles the actual retry efforts based on this flag and a few other factors (like if max retries have been attempted). Currently, if an error code isn't explicitly accounted for, it falls back to being an "unknown error while sending" and is marked as not retryable. However, SMTP [defines the 4yz class of error codes as being retryable](https://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes.xhtml). ### Summary of Changes We add fallback logic at the end of the `responseCode` specific block to mark the 4yz class of error codes as retryable. While the message here is less specific, that is okay since any codes we want to explicitly account for are handled above it. The main thing here is that these should be retried. --- apps/backend/src/lib/emails-low-level.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/apps/backend/src/lib/emails-low-level.tsx b/apps/backend/src/lib/emails-low-level.tsx index 0183c28a7..ba58de12a 100644 --- a/apps/backend/src/lib/emails-low-level.tsx +++ b/apps/backend/src/lib/emails-low-level.tsx @@ -18,6 +18,13 @@ export function isSecureEmailPort(port: number | string) { return parsedPort === 465 || parsedPort === 2465; } +function is4yzSMTPResponseCode(code: number | undefined) { + if (typeof code !== 'number') { + return false; + } + return code >= 400 && code < 500; +} + export type LowLevelEmailConfig = { host: string, port: number, @@ -168,6 +175,16 @@ async function _lowLevelSendEmailWithoutRetries(options: LowLevelSendEmailOption message: 'Connection to email server was lost unexpectedly. This could be due to incorrect email server port configuration or a temporary network issue. Please verify your configuration and try again.', } as const); } + // 4yz error codes are considered temporary errors in SMTP, so they should be retried anyway + // This is fallback logic for a code we don't explicitly capture but should still be retryable and we have the code + if (is4yzSMTPResponseCode(responseCode)) { + return Result.error({ + rawError: error, + errorType: 'TRANSIENT_NEGATIVE_COMPLETION_REPLY', + canRetry: true, + message: 'The email server returned a temporary error. Please try again later.' + getServerResponse(error), + } as const); + } } // ============ temporary error ============