Retry sending emails on transient errors#1309
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📝 Walkthrough📝 Walkthrough🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1309 +/- ##
==========================================
- Coverage 65.65% 65.33% -0.33%
==========================================
Files 154 154
Lines 6619 6652 +33
Branches 1639 1650 +11
==========================================
Hits 4346 4346
- Misses 2120 2151 +31
- Partials 153 155 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@backend/util/sendMail.ts`:
- Around line 34-35: The assigned logger variable (const logger =
context?.logger ?? console) creates a union type (winston.Logger | Console) that
breaks type-checking when passed into withRetries; remove passing logger into
withRetries and drop the logger field from RetryOptions (or alternatively change
RetryOptions.logger to a minimal shape like { info: (...args:any[]) => void } if
you need it later), and keep using logInfo (logger.info.bind(logger)) where
needed; update the withRetries call sites to stop supplying logger and adjust
the RetryOptions definition and any consumers accordingly.
🧹 Nitpick comments (2)
backend/util/sendMail.ts (2)
79-86: Unusedloggerparameter and misleadingmaxRetriesname.Two issues in
RetryOptions/withRetries:
Dead parameter:
logger(line 81/90) is destructured but never referenced in the function body — onlylogInfois used. Remove it to avoid the type mismatch described above and reduce confusion.Naming:
maxRetries: 3actually produces 3 total attempts (loop:attempt <= maxRetries). Someone settingmaxRetries: 1would expect one retry but get only one attempt total (i.e., zero retries). Consider renaming tomaxAttempts, or adjusting the loop toattempt <= maxRetries + 1.Suggested diff
interface RetryOptions { - maxRetries: number - logger?: winston.Logger - logInfo?: (message: string) => void + maxAttempts: number + log?: (message: string) => void operationName: string operation: (attempt: number) => Promise<void> isTransientError: (error: unknown) => boolean } async function withRetries({ - maxRetries, - logger, - logInfo, + maxAttempts, + log: logFn, operationName, operation, isTransientError, }: RetryOptions) { const BASE_DELAY_MS = 1000 const jitter = () => Math.floor(Math.random() * 250) - const log = logInfo ?? ((message: string) => console.log(message)) + const log = logFn ?? ((message: string) => console.log(message)) - for (let attempt = 1; attempt <= maxRetries; attempt++) { + for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { await operation(attempt) return } catch (error: any) { - if (attempt >= maxRetries || !isTransientError(error)) { + if (attempt >= maxAttempts || !isTransientError(error)) { throw error } log( - `${operationName} failed (attempt ${attempt}/${maxRetries}, retrying): ${ + `${operationName} failed (attempt ${attempt}/${maxAttempts}, retrying): ${ error?.message ?? error }`, )And update the call site accordingly:
await withRetries({ - maxRetries: 3, - logger, - logInfo, + maxAttempts: 3, + log: logInfo, operationName: "SMTP send",Also applies to: 88-98
108-112: Considerwarnlevel for retry-failure log messages.Transient failures being retried are logged at
infolevel (sincelogInfoislogger.info.bind(logger)). Usingwarnwould make these easier to surface in monitoring/alerting and better reflects the semantics — something went wrong, but it's being handled.
Summary by CodeRabbit