diff --git a/src/token-processor/util/errors.ts b/src/token-processor/util/errors.ts index 07119aa5..2dfb2bae 100644 --- a/src/token-processor/util/errors.ts +++ b/src/token-processor/util/errors.ts @@ -95,22 +95,22 @@ export class StacksNodeHttpError extends Error { export function getUserErrorInvalidReason(error: UserError): DbJobInvalidReason { switch (true) { - case error instanceof MetadataSizeExceededError: - return DbJobInvalidReason.metadataSizeExceeded; case error instanceof ImageSizeExceededError: return DbJobInvalidReason.imageSizeExceeded; - case error instanceof MetadataTimeoutError: - return DbJobInvalidReason.metadataTimeout; + case error instanceof MetadataSizeExceededError: + return DbJobInvalidReason.metadataSizeExceeded; case error instanceof ImageTimeoutError: return DbJobInvalidReason.imageTimeout; - case error instanceof MetadataParseError: - return DbJobInvalidReason.metadataParseFailed; + case error instanceof MetadataTimeoutError: + return DbJobInvalidReason.metadataTimeout; case error instanceof ImageParseError: return DbJobInvalidReason.imageParseFailed; - case error instanceof MetadataHttpError: - return DbJobInvalidReason.metadataHttpError; + case error instanceof MetadataParseError: + return DbJobInvalidReason.metadataParseFailed; case error instanceof ImageHttpError: return DbJobInvalidReason.imageHttpError; + case error instanceof MetadataHttpError: + return DbJobInvalidReason.metadataHttpError; case error instanceof SmartContractClarityError: return DbJobInvalidReason.tokenContractClarityError; default: diff --git a/src/token-processor/util/metadata-helpers.ts b/src/token-processor/util/metadata-helpers.ts index 42b37870..ba6efc47 100644 --- a/src/token-processor/util/metadata-helpers.ts +++ b/src/token-processor/util/metadata-helpers.ts @@ -65,7 +65,11 @@ export async function fetchAllMetadataLocalesFromBaseUri( try { const rawMetadataLocales: RawMetadataLocale[] = []; - const defaultMetadata = await getMetadataFromUri(tokenUri); + const defaultMetadata = await getMetadataFromUri( + tokenUri, + contract.principal, + token.token_number + ); rawMetadataLocales.push({ metadata: defaultMetadata, default: true, @@ -83,7 +87,11 @@ export async function fetchAllMetadataLocalesFromBaseUri( continue; } const localeUri = getTokenSpecificUri(uri, token.token_number, locale); - const localeMetadata = await getMetadataFromUri(localeUri); + const localeMetadata = await getMetadataFromUri( + localeUri, + contract.principal, + token.token_number + ); rawMetadataLocales.push({ metadata: localeMetadata, locale: locale, @@ -234,9 +242,14 @@ async function parseMetadataForInsertion( * @param httpUrl - URL to fetch * @returns Response text */ -export async function fetchMetadata(httpUrl: URL): Promise { +export async function fetchMetadata( + httpUrl: URL, + contract_principal: string, + token_number: bigint +): Promise { const url = httpUrl.toString(); try { + logger.info(`MetadataFetch for ${contract_principal}#${token_number} from ${url}`); const result = await request(url, { method: 'GET', throwOnError: true, @@ -266,7 +279,11 @@ export async function fetchMetadata(httpUrl: URL): Promise { } } -export async function getMetadataFromUri(token_uri: string): Promise { +export async function getMetadataFromUri( + token_uri: string, + contract_principal: string, + token_number: bigint +): Promise { // Support JSON embedded in a Data URL if (new URL(token_uri).protocol === 'data:') { const dataUrl = parseDataUrl(token_uri); @@ -292,7 +309,7 @@ export async function getMetadataFromUri(token_uri: string): Promise { const server = await startTimeoutServer(100); await expect( processImageCache('http://127.0.0.1:9999/', contract, tokenNumber) - ).rejects.toThrow(MetadataTimeoutError); + ).rejects.toThrow(ImageTimeoutError); await closeTestServer(server); }, 10000); @@ -38,7 +38,7 @@ describe('Image cache', () => { const server = await startTestResponseServer('not found', 404); await expect( processImageCache('http://127.0.0.1:9999/', contract, tokenNumber) - ).rejects.toThrow(MetadataHttpError); + ).rejects.toThrow(ImageHttpError); await closeTestServer(server); }, 10000); }); diff --git a/tests/token-queue/metadata-helpers.test.ts b/tests/token-queue/metadata-helpers.test.ts index c512ce5d..1f4b321a 100644 --- a/tests/token-queue/metadata-helpers.test.ts +++ b/tests/token-queue/metadata-helpers.test.ts @@ -7,7 +7,6 @@ import { getTokenSpecificUri, fetchMetadata, } from '../../src/token-processor/util/metadata-helpers'; -import { RetryableJobError } from '../../src/token-processor/queue/errors'; describe('Metadata Helpers', () => { test('performs timed and limited request', async () => { @@ -24,7 +23,7 @@ describe('Metadata Helpers', () => { .reply(200, 'hello'); setGlobalDispatcher(agent); - const result = await fetchMetadata(url); + const result = await fetchMetadata(url, 'ABCD.test', 1n); expect(result).toBe('hello'); }); @@ -40,7 +39,9 @@ describe('Metadata Helpers', () => { .reply(200, '[{"test-bad-json": true}]'); setGlobalDispatcher(agent); - await expect(getMetadataFromUri('http://test.io/1.json')).rejects.toThrow(/JSON parse error/); + await expect(getMetadataFromUri('http://test.io/1.json', 'ABCD.test', 1n)).rejects.toThrow( + /JSON parse error/ + ); }); test('throws metadata http errors', async () => { @@ -56,7 +57,7 @@ describe('Metadata Helpers', () => { .reply(500, { message: 'server error' }); setGlobalDispatcher(agent); - await expect(fetchMetadata(url)).rejects.toThrow(MetadataHttpError); + await expect(fetchMetadata(url, 'ABCD.test', 1n)).rejects.toThrow(MetadataHttpError); }); test('does not throw on raw metadata with null or stringable values', async () => { @@ -91,7 +92,9 @@ describe('Metadata Helpers', () => { .reply(200, crashPunks1); setGlobalDispatcher(agent); - await expect(getMetadataFromUri('http://test.io/1.json')).resolves.not.toThrow(); + await expect( + getMetadataFromUri('http://test.io/1.json', 'ABCD.test', 1n) + ).resolves.not.toThrow(); }); test('fetches typed raw metadata', async () => { @@ -127,7 +130,7 @@ describe('Metadata Helpers', () => { .reply(200, json); setGlobalDispatcher(agent); - const metadata = await getMetadataFromUri('http://test.io/1.json'); + const metadata = await getMetadataFromUri('http://test.io/1.json', 'ABCD.test', 1n); expect(metadata.name).toBe('Mutant Monkeys #27'); expect(metadata.image).toBe( 'https://byzantion.mypinata.cloud/ipfs/QmbNC9qvcYZugaeGeReDhyYiNH7oPzrCX1cZUnQeszFz4P' @@ -154,7 +157,7 @@ describe('Metadata Helpers', () => { .reply(200, json); setGlobalDispatcher(agent); - const metadata = await getMetadataFromUri('http://test.io/1.json'); + const metadata = await getMetadataFromUri('http://test.io/1.json', 'ABCD.test', 1n); expect(metadata.name).toBe('Boombox [4th Edition]'); expect(metadata.description).toBe( 'The first ever Boombox to exist IRL, this art was created by 3D printing a model and photographing it under some very Boomerific lighting. 💥' @@ -228,6 +231,6 @@ describe('Metadata Helpers', () => { .replyWithError(Object.assign(new TypeError(), { cause: new Error('read ECONNRESET') })); setGlobalDispatcher(agent); - await expect(fetchMetadata(url)).rejects.toThrow(MetadataHttpError); + await expect(fetchMetadata(url, 'ABCD.test', 1n)).rejects.toThrow(MetadataHttpError); }); });