Skip to content

Commit a42657f

Browse files
committed
chore: make sure we dont cache errors
1 parent d483965 commit a42657f

2 files changed

Lines changed: 20 additions & 5 deletions

File tree

packages/assets-controllers/src/TokenListService.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,12 @@ export class TokenListService {
4848
* @returns A map of lowercase token address → token metadata.
4949
*/
5050
async fetchTokensByChainId(chainId: Hex): Promise<TokenListMap> {
51-
return await this.#queryClient.fetchQuery({
52-
queryKey: ['TokenListService:fetchTokensByChainId', chainId],
51+
const queryKey = ['TokenListService:fetchTokensByChainId', chainId];
52+
// On failure, TanStack Query v5 sets isInvalidated=true and leaves state.data
53+
// undefined, so the next fetchQuery call always triggers a fresh network request
54+
// rather than serving the cached error. No manual cache eviction is needed.
55+
return this.#queryClient.fetchQuery({
56+
queryKey,
5357
queryFn: async () => {
5458
const list = (await fetchTokenListByChainId(
5559
chainId,

packages/assets-controllers/src/TokensController.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ import {
5353
TOKEN_METADATA_NO_SUPPORT_ERROR,
5454
TokenRwaData,
5555
} from './token-service';
56-
import type { TokenListToken } from './TokenListController';
56+
import type { TokenListMap, TokenListToken } from './TokenListController';
5757
import type { TokenListService } from './TokenListService';
5858
import type { Token } from './TokenRatesController';
5959
import type { TokensControllerMethodActions } from './TokensController-method-action-types';
@@ -278,13 +278,24 @@ export class TokensController extends BaseController<
278278
// Fetch all chain data concurrently before touching state so the async gap
279279
// is as short as possible and we never hold a stale T0 snapshot while
280280
// awaiting individual chain requests.
281-
const chainDataEntries = await Promise.all(
281+
// Promise.allSettled ensures a transient error on one chain does not
282+
// prevent other chains from being enriched.
283+
const results = await Promise.allSettled(
282284
chainIds.map(async (chainId) => {
283285
const data = await tokenListService.fetchTokensByChainId(chainId);
284286
return [chainId, data] as const;
285287
}),
286288
);
287-
const chainDataMap = Object.fromEntries(chainDataEntries);
289+
const chainDataMap = Object.fromEntries(
290+
results
291+
.filter(
292+
(
293+
result,
294+
): result is PromiseFulfilledResult<readonly [Hex, TokenListMap]> =>
295+
result.status === 'fulfilled',
296+
)
297+
.map((result) => result.value),
298+
);
288299

289300
// Read selectedAddress inside the updater so it reflects the live account
290301
// at the moment the state write happens, not a snapshot taken before the

0 commit comments

Comments
 (0)