@@ -2,6 +2,9 @@ import { clampString } from "@/lib/edge/utils";
22
33const RESEND_EMAILS_API_URL = "https://api.resend.com/emails" ;
44const NETWORK_ERROR_MESSAGE = "Unable to reach Resend email API" ;
5+ const DEFAULT_RETRY_DEADLINE_MS = 15_000 ;
6+ const DEFAULT_MAX_ATTEMPTS = 15 ;
7+ const RETRY_INTERVAL_MS = 1_000 ;
58
69export interface ResendEmailPayload {
710 from : string ;
@@ -47,6 +50,15 @@ export function sanitizeProviderError(value: unknown): string {
4750 return clampString ( message , 180 ) ;
4851}
4952
53+ function sanitizeNetworkError ( error : unknown ) : string {
54+ if ( error instanceof Error ) {
55+ const name = error . name || "Error" ;
56+ const message = error . message || "network_failed" ;
57+ return clampString ( `${ name } : ${ message } ` , 180 ) ;
58+ }
59+ return clampString ( String ( error || "network_failed" ) , 180 ) ;
60+ }
61+
5062function isRetryableStatus ( status : number ) : boolean {
5163 return status === 429 || status >= 500 ;
5264}
@@ -55,12 +67,6 @@ function delay(ms: number): Promise<void> {
5567 return new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
5668}
5769
58- function backoffMs ( attempts : number ) : number {
59- const base = attempts <= 1 ? 450 : 1_350 ;
60- const jitter = Math . floor ( Math . random ( ) * ( attempts <= 1 ? 151 : 451 ) ) ;
61- return base + jitter ;
62- }
63-
6470async function fetchWithTimeout ( input : {
6571 apiKey : string ;
6672 body : ResendEmailPayload ;
@@ -92,8 +98,12 @@ export async function sendResendEmailWithRetry(input: {
9298 maxAttempts ?: number ;
9399} ) : Promise < ResendSendResult > {
94100 const startedAt = Date . now ( ) ;
95- const deadlineAt = startedAt + Math . max ( 500 , input . deadlineMs ?? 9_000 ) ;
96- const maxAttempts = Math . max ( 1 , Math . trunc ( input . maxAttempts ?? 3 ) ) ;
101+ const deadlineAt =
102+ startedAt + Math . max ( 500 , input . deadlineMs ?? DEFAULT_RETRY_DEADLINE_MS ) ;
103+ const maxAttempts = Math . max (
104+ 1 ,
105+ Math . trunc ( input . maxAttempts ?? DEFAULT_MAX_ATTEMPTS ) ,
106+ ) ;
97107 const fetchImpl = input . fetchImpl ?? fetch ;
98108 let attempts = 0 ;
99109 let status = 0 ;
@@ -145,15 +155,15 @@ export async function sendResendEmailWithRetry(input: {
145155 reason,
146156 } ;
147157 }
148- } catch {
158+ } catch ( error ) {
149159 status = 0 ;
150160 payload = { } ;
151161 reason = "network_failed" ;
152- errorMessage = NETWORK_ERROR_MESSAGE ;
162+ errorMessage = ` ${ NETWORK_ERROR_MESSAGE } : ${ sanitizeNetworkError ( error ) } ` ;
153163 }
154164
155165 if ( attempts >= maxAttempts ) break ;
156- const waitMs = backoffMs ( attempts ) ;
166+ const waitMs = RETRY_INTERVAL_MS ;
157167 if ( Date . now ( ) + waitMs >= deadlineAt ) break ;
158168 await delay ( waitMs ) ;
159169 }
0 commit comments