Skip to content

Conversation

@terrerox
Copy link
Contributor

@terrerox terrerox commented Feb 3, 2026

Description

Implement retry utility to handle 429 rate limit errors with configurable backoff strategy, extract rate limit info
from response headers, and apply it to public shared folder content requests to improve reliability under rate
limiting conditions.

Related Issues

Related Pull Requests

Checklist

  • Changes have been tested locally.
  • Unit tests have been written or updated as necessary.
  • The code adheres to the repository's coding standards.
  • Relevant documentation has been added or updated.
  • No new warnings or errors have been introduced.
  • SonarCloud issues have been reviewed and addressed.
  • QA Passed

Testing Process

Additional Notes

  Implement retry utility to handle 429 rate limit errors with configurable backoff strategy, extract rate limit info
   from response headers, and apply it to public shared folder content requests to improve reliability under rate
  limiting conditions.
@terrerox terrerox requested review from a team, CandelR and larryrider as code owners February 3, 2026 04:27
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 3, 2026

Deploying drive-web with  Cloudflare Pages  Cloudflare Pages

Latest commit: 34d5f3b
Status: ✅  Deploy successful!
Preview URL: https://82de3e28.drive-web.pages.dev
Branch Preview URL: https://feature-retry-with-backoff.drive-web.pages.dev

View logs

@terrerox terrerox self-assigned this Feb 3, 2026
Copy link
Collaborator

@CandelR CandelR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this accompanied by some kind of visual information for the user? I don't see the point of this PR from the user's point of view, as they will be waiting at least 60 seconds without knowing what is happening, which is an enormous amount of time.

return typeof error === 'object' && error !== null;
}

function isRateLimitError(error: unknown): boolean {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use arrow functions to be consistent with rest of the codebase

return (
error.status === 429 ||
error.statusCode === 429 ||
error.response?.status === 429 ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remember correctly, there are status codes, use them or add this one if it is not there

return undefined;
}

const resetValueMs = Number.parseInt(headers['x-ratelimit-reset'], 10);
Copy link
Collaborator

@CandelR CandelR Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the unit that return the server is in miliseconds?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

}
}

throw new Error('Maximum retries exceeded');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this error reachable? Check it with tests

maxRetries: 5,
maxDelay: 60000,
onRetry: (attempt, delay) => {
console.log(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe better use console warn if want to log the retry for when user records the console and send to us

Comment on lines 52 to 54
if (!isErrorWithStatus(error) || !error.headers) {
return undefined;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is already checked in isRateLimitError, I think that never will reach this code

};
}

export async function retryWithBackoff<T>(fn: () => Promise<T>, options: RetryOptions = {}): Promise<T> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add jsdoc to this exported function

  - Remove maxDelay option and related fallback logic
  - Simplify rate limit detection to only check status codes (429)
  - Update rate limit header from 'x-ratelimit-reset' to 'x-internxt-ratelimit-reset'
  - Remove limit and remaining fields from RateLimitInfo interface
  - Add user-facing toast notification on first retry attempt
  - Convert functions to arrow functions for consistency
  - Add HTTP_CODES.TOO_MANY_REQUESTS constant
  - Add JSDoc documentation to retryWithBackoff function
  - Add internationalization support for retry notification
  - Update tests to reflect new behavior and validate toast integration
  - Fix loop condition to prevent unreachable code
@terrerox terrerox marked this pull request as draft February 4, 2026 03:49
@terrerox terrerox force-pushed the feature/retry-with-backoff branch from 52a8dc6 to cd0f3ad Compare February 4, 2026 15:16
@terrerox terrerox marked this pull request as ready for review February 4, 2026 15:22
@terrerox terrerox requested review from CandelR and sg-gs February 4, 2026 15:23

if (!hasShownRateLimitToast) {
hasShownRateLimitToast = true;
notificationsService.show({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not mix UI related things with pure logic like this function. Return something that allows the function consumer to determine if showing this notification or not proceeds

@terrerox terrerox requested a review from sg-gs February 4, 2026 16:38
@terrerox terrerox force-pushed the feature/retry-with-backoff branch from 56215d9 to 6b7760c Compare February 5, 2026 03:32
"link-updated": "Linkeinstellungen aktualisiert",
"link-deleted": "Link gelöscht",
"links-deleted": "Link(s) gelöscht"
"links-deleted": "Link(s) gelöscht",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems that here is missing error-deleting-links translation, can you add it? :)

Comment on lines 140 to 145
hasShownRateLimitNotification = true;
notificationsService.show({
text: t('shared-links.toast.rate-limit-retry'),
type: ToastType.Warning,
duration: Infinity,
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this out of the service, return the error, and handle it in the manager component of the UI to decide what to display. This way, we try to keep it clean. Even if there is a function with the notificationService in this service, we will try not to mix it up any further :)

@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 5, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants