Skip to content

Conversation

@sanchitmehta94
Copy link
Contributor

@sanchitmehta94 sanchitmehta94 commented Jan 7, 2026

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

📋 Changes

Summary

This change addresses *auth0/react-native-auth0#1374 by improving the reliability of token renewal in unstable network conditions.

Background / Problem

A scenario highlighted by the community:

  1. Request A calls getCredentials() and initiates a token refresh.
  2. The request successfully reaches Auth0 and a new access token is issued.
  3. The response fails to reach the client due to a transient network issue.
  4. Later, Request B attempts another call using the same (now stale) access token.

On mobile networks, which are often unreliable, this scenario is realistic. In such cases, even if the user retries later on a stable network, the refresh attempt may fail because the refresh token could already be expired by that time.

Proposed Solution

This PR introduces retry support for transient failures to better leverage Auth0’s refresh token rotation overlap period, allowing safe retries when the server-side renewal succeeds but the response never reaches the client.

Changes Included

  • Implement exponential backoff retry logic for transient errors in CredentialsManager

  • Add a configurable maxRetries parameter (default: 0, disabled)

  • Introduce Auth0APIError.isRetryable utility for SDK-wide retry detection

  • Add comprehensive documentation to EXAMPLES.md, covering:

    • Retry behavior for network errors, rate limiting (429), and server errors (5xx)
    • Configuration guidance (recommended maximum of 2 retries)
    • Auth0 refresh token rotation overlap period requirement (minimum 180 seconds)

Outcome

The retry mechanism improves resilience in real-world mobile conditions by safely retrying renewal requests within the refresh token overlap window, reducing unnecessary authentication failures without changing default behavior.

📎 References

🎯 Testing

@sanchitmehta94 sanchitmehta94 requested a review from a team as a code owner January 7, 2026 06:19
self.storeKey = storeKey
self.authentication = authentication
self.sendableStorage = SendableBox(value: storage)
self.maxRetries = max(0, maxRetries)
Copy link
Contributor Author

@sanchitmehta94 sanchitmehta94 Jan 7, 2026

Choose a reason for hiding this comment

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

i havent added automatic retry at network request level because that would be ebhavioral changes . so currently only looking to address the github issue where credential renwewal can fail in mobile patch network scenario.

currently there is dpop hanlding for retry but its a bit coupled. Will plan in major release to move retry at network level and make it more reusable across SDK . this would need more changes.

@sanchitmehta94 sanchitmehta94 added wip and removed wip labels Jan 7, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces an automatic retry mechanism for credential renewal operations to improve reliability when facing transient network failures, particularly important for mobile applications operating on unstable networks.

Key Changes

  • Adds configurable retry support with exponential backoff for credential renewal failures
  • Implements isRetryable property on Auth0APIError to identify transient errors (network issues, rate limiting, server errors)
  • Includes comprehensive test coverage for various retry scenarios including success, exhaustion, and non-retryable errors

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
EXAMPLES.md Adds comprehensive documentation explaining the retry mechanism, configuration, and Auth0 tenant setup requirements
Auth0Tests/Responses.swift Adds test helper functions for simulating network errors, rate limiting, and server errors
Auth0Tests/CredentialsManagerSpec.swift Adds extensive test suite covering retry scenarios, exponential backoff, and compatibility with async/await and Combine
Auth0/CredentialsManager.swift Implements retry logic with exponential backoff in credential renewal flow, adds maxRetries parameter
Auth0/Auth0APIError.swift Adds isRetryable property to identify transient errors suitable for retry

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

EXAMPLES.md Outdated
1. Request A calls `credentials()` and starts a token refresh
2. Request A successfully hits the server and gets new credentials
3. Request A fails on the way back (network issue), never reaching the client
4. Later, request B retries with the same (old) refresh token
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

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

The wording in step 4 could be misleading. It says "Later, request B retries with the same (old) refresh token" which suggests a different, separate request happens later. However, the retry mechanism implemented automatically retries the SAME request. Consider rephrasing to clarify this is an automatic retry of the failed request, not a separate subsequent request. For example: "The retry mechanism automatically retries the request with the same (old) refresh token".

Suggested change
4. Later, request B retries with the same (old) refresh token
4. The retry mechanism automatically retries the failed request using the same (old) refresh token

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

callback: callback)
}
} else {
complete()
Copy link
Contributor

Choose a reason for hiding this comment

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

lets call complete() as soon as failure block is recieved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

forceRenewal: Bool,
retryCount: Int,
callback: @escaping (CredentialsManagerResult<Credentials>) -> Void) {
SynchronizationBarrier.shared.execute { complete in
Copy link
Contributor

Choose a reason for hiding this comment

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

[weak self]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Credential Manager is a struct

@sanchitmehta94 sanchitmehta94 enabled auto-merge (squash) January 7, 2026 09:09
@sanchitmehta94 sanchitmehta94 merged commit e427376 into master Jan 7, 2026
11 checks passed
@sanchitmehta94 sanchitmehta94 deleted the SDK-7415 branch January 7, 2026 09:14
@sanchitmehta94 sanchitmehta94 mentioned this pull request Jan 7, 2026
@sanchitmehta94 sanchitmehta94 changed the title feat: Add automatic retry mechanism for credential renewal feat: Add automatic retry mechanism for credential renewal to improve the reliability in unstable network conditions Jan 7, 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.

4 participants