From eca4f80da9d643f30542c271732b61cab2ea5032 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Thu, 12 May 2022 19:56:12 -0230 Subject: [PATCH] Revert "Revert "[Token Detection V2] 1 of 7 - Throw on failure for fetchTokenMetadata in token service (#812)" (#824)" (#827) This reverts commit a25d90906137f85ea9853018f7c3fbe0cfd67df1. It was temporarily reverted to avoid making a breaking change in v29.0.1. --- src/apis/token-service.test.ts | 86 ++++++++++++++++++++-------------- src/apis/token-service.ts | 10 ++-- 2 files changed, 57 insertions(+), 39 deletions(-) diff --git a/src/apis/token-service.test.ts b/src/apis/token-service.test.ts index 758229f52b9..f69656ab149 100644 --- a/src/apis/token-service.test.ts +++ b/src/apis/token-service.test.ts @@ -1,6 +1,10 @@ import nock from 'nock'; import { NetworksChainId } from '../network/NetworkController'; -import { fetchTokenList, fetchTokenMetadata } from './token-service'; +import { + fetchTokenList, + fetchTokenMetadata, + FETCH_TOKEN_METADATA_ERROR, +} from './token-service'; const TOKEN_END_POINT_API = 'https://token-api.metaswap.codefi.network'; @@ -233,7 +237,7 @@ describe('Token service', () => { expect(token).toStrictEqual(sampleToken); }); - it('should return undefined if the fetch is aborted', async () => { + it('should throw error if the fetch is aborted', async () => { const abortController = new AbortController(); nock(TOKEN_END_POINT_API) .get(`/tokens/${NetworksChainId.mainnet}`) @@ -242,49 +246,49 @@ describe('Token service', () => { .reply(200, sampleTokenList) .persist(); - const fetchPromise = fetchTokenMetadata( - NetworksChainId.mainnet, - '0x514910771af9ca656af840dff83e8264ecf986ca', - abortController.signal, - ); - abortController.abort(); - - expect(await fetchPromise).toBeUndefined(); + await expect(async () => { + await fetchTokenMetadata( + NetworksChainId.mainnet, + '0x514910771af9ca656af840dff83e8264ecf986ca', + abortController.signal, + ); + abortController.abort(); + }).rejects.toThrow(FETCH_TOKEN_METADATA_ERROR); }); - it('should return undefined if the fetch fails with a network error', async () => { + it('should throw error if the fetch fails with a network error', async () => { const { signal } = new AbortController(); nock(TOKEN_END_POINT_API) .get(`/tokens/${NetworksChainId.mainnet}`) .replyWithError('Example network error') .persist(); - const result = await fetchTokenMetadata( - NetworksChainId.mainnet, - '0x514910771af9ca656af840dff83e8264ecf986ca', - signal, - ); - - expect(result).toBeUndefined(); + await expect(async () => { + await fetchTokenMetadata( + NetworksChainId.mainnet, + '0x514910771af9ca656af840dff83e8264ecf986ca', + signal, + ); + }).rejects.toThrow(FETCH_TOKEN_METADATA_ERROR); }); - it('should return undefined if the fetch fails with an unsuccessful status code', async () => { + it('should throw error if the fetch fails with an unsuccessful status code', async () => { const { signal } = new AbortController(); nock(TOKEN_END_POINT_API) .get(`/tokens/${NetworksChainId.mainnet}`) .reply(500) .persist(); - const result = await fetchTokenMetadata( - NetworksChainId.mainnet, - '0x514910771af9ca656af840dff83e8264ecf986ca', - signal, - ); - - expect(result).toBeUndefined(); + await expect(async () => { + await fetchTokenMetadata( + NetworksChainId.mainnet, + '0x514910771af9ca656af840dff83e8264ecf986ca', + signal, + ); + }).rejects.toThrow(FETCH_TOKEN_METADATA_ERROR); }); - it('should return undefined if the fetch fails with a timeout', async () => { + it('should throw error if the fetch fails with a timeout', async () => { const { signal } = new AbortController(); nock(TOKEN_END_POINT_API) .get(`/tokens/${NetworksChainId.mainnet}`) @@ -293,14 +297,26 @@ describe('Token service', () => { .reply(200, sampleTokenList) .persist(); - const result = await fetchTokenMetadata( - NetworksChainId.mainnet, - '0x514910771af9ca656af840dff83e8264ecf986ca', - signal, - { timeout: ONE_MILLISECOND }, - ); - - expect(result).toBeUndefined(); + await expect(async () => { + await fetchTokenMetadata( + NetworksChainId.mainnet, + '0x514910771af9ca656af840dff83e8264ecf986ca', + signal, + { timeout: ONE_MILLISECOND }, + ); + }).rejects.toThrow(FETCH_TOKEN_METADATA_ERROR); }); }); + + it('should call the tokens api and return undefined', async () => { + const { signal } = new AbortController(); + nock(TOKEN_END_POINT_API) + .get(`/tokens/${NetworksChainId.mainnet}`) + .reply(404, undefined) + .persist(); + + const tokens = await fetchTokenList(NetworksChainId.mainnet, signal); + + expect(tokens).toBeUndefined(); + }); }); diff --git a/src/apis/token-service.ts b/src/apis/token-service.ts index 139a1738b1c..4028c9721a2 100644 --- a/src/apis/token-service.ts +++ b/src/apis/token-service.ts @@ -1,6 +1,8 @@ import { timeoutFetch } from '../util'; const END_POINT = 'https://token-api.metaswap.codefi.network'; +export const FETCH_TOKEN_METADATA_ERROR = + 'TokenService Error: No response from fetchTokenMetadata'; /** * Get the tokens URL for a specific network. @@ -63,18 +65,18 @@ export async function fetchTokenList( * @param options.timeout - The fetch timeout. * @returns The token metadata, or `undefined` if the request was cancelled. */ -export async function fetchTokenMetadata( +export async function fetchTokenMetadata( chainId: string, tokenAddress: string, abortSignal: AbortSignal, { timeout = defaultTimeout } = {}, -): Promise { +): Promise { const tokenMetadataURL = getTokenMetadataURL(chainId, tokenAddress); const response = await queryApi(tokenMetadataURL, abortSignal, timeout); if (response) { - return parseJsonResponse(response); + return parseJsonResponse(response) as Promise; } - return undefined; + throw new Error(FETCH_TOKEN_METADATA_ERROR); } /**