-
-
Notifications
You must be signed in to change notification settings - Fork 254
fix: force timeout after 30s token detection #7106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@metamaskbot publish-preview |
|
Preview builds have been published. See these instructions for more information about preview builds. Expand for full list of packages and versions. |
| supportedNetworks, | ||
| }); | ||
|
|
||
| return await Promise.race([apiCallPromise, timeoutPromise]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm can we reuse our existing utils? E.g.
async #attemptAccountAPIDetection(
chainsToDetectUsingAccountAPI: Hex[],
addressToDetect: string,
supportedNetworks: number[] | null,
) {
// from controller-utils
const result = await safelyExecuteWithTimeout(
async () => {
return this.#addDetectedTokensViaAPI({
chainIds: chainsToDetectUsingAccountAPI,
selectedAddress: addressToDetect,
supportedNetworks,
});
},
false,
ACCOUNTS_API_TIMEOUT_MS,
);
if (!result) {
return { result: 'failed' };
}
return result;
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooh true , comment addressed here e5b43d0
|
@metamaskbot publish-preview |
|
Preview builds have been published. See these instructions for more information about preview builds. Expand for full list of packages and versions. |
Explanation
What is the current state and why does it need to change?
Currently, when
TokenDetectionControlleruses the Accounts API to detect tokens, API calls can hang indefinitely if the API is slow, unresponsive, or experiencing network issues. This causes the entire token detection process to freeze without any fallback mechanism, resulting in a poor user experience where tokens are never detected.What is the solution and how does it work?
This PR adds 30-second timeout protection for Accounts API calls in
TokenDetectionController:Added
ACCOUNTS_API_TIMEOUT_MSconstant (30000ms) to define the timeout thresholdWrapped Accounts API calls with
Promise.race()between the actual API call and a timeout promiseWhen timeout occurs, the promise rejects and is caught, triggering an automatic fallback to RPC-based token detection
Properly cleans up the timeout in a
finallyblock to prevent memory leaksIncludes error logging for debugging timeout and failure events
The timeout mechanism ensures that:
If the API responds within 30 seconds, detection proceeds normally via the API
If the API takes longer than 30 seconds, the timeout fires and RPC detection takes over
Users always get token detection results, either via API or RPC fallback
Changes that might not be obvious
The timeout is implemented in the
#attemptAccountAPIDetectionprivate method, which wraps the existing#addDetectedTokensViaAPIcall. This ensures the timeout protection applies to all Accounts API token detection flows without requiring changes to the core detection logic.References
Improves reliability of token detection by preventing indefinite hangs
Ensures users always get token detection results through automatic RPC fallback
Related to ongoing work to improve Accounts API reliability and user experience
Checklist
I've updated the test suite for new or updated code as appropriate
Added comprehensive timeout test using fake timers to simulate 30-second timeout scenario
Test verifies that API is called, timeout triggers, RPC fallback occurs, and tokens are successfully added
I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
I've communicated my changes to consumers by updating changelogs for packages I've changed, highlighting breaking changes as necessary
CHANGELOG.mdwith timeout protection fixI've prepared draft pull requests for clients and consumer packages to resolve any breaking changes
Technical Implementation Details
Key Files Changed
TokenDetectionController.tsACCOUNTS_API_TIMEOUT_MSconstant (30000ms)#attemptAccountAPIDetectionmethod to implement timeout protectionPromise.race()to race between API call and timeout promisefinallyblock to prevent memory leaksTokenDetectionController.test.ts'should timeout and fallback to RPC when Accounts API call takes longer than 30 seconds'sinon.useFakeTimers()to simulate time advancementCode Flow
Testing Strategy
The test uses fake timers to simulate the 30-second timeout without actually waiting 30 seconds:
Impact
User Experience
Performance
Reliability
Note
Adds a 30s timeout to Accounts API token detection with RPC fallback, and refactors balance fetchers to return
unprocessedChainIdsso controllers can retry unsupported chains via RPC.TokenDetectionController):ACCOUNTS_API_TIMEOUT_MS(30s) and wrap API calls withsafelyExecuteWithTimeout; on timeout/failure, fall back to RPC.unprocessedNetworksand add those chains to RPC detection.fetch()to return{ balances, unprocessedChainIds }inAccountsApiBalanceFetcherandRpcBalanceFetcher.unprocessedNetworks(decimal) to hexunprocessedChainIds; aggregate across batches.AccountTrackerRPC fetcher wrapper, filter out staked entries whenincludeStakedAssetsis false while preservingunprocessedChainIds.AccountTrackerControllerandTokenBalancesControllerto consume new fetcher result shape and re-queueunprocessedChainIdsfor fallback fetchers.CurrencyRateControllerresponses.CHANGELOG.mdto reflect timeout protection and unprocessed network handling.Written by Cursor Bugbot for commit 7a813ba. This will update automatically on new commits. Configure here.