Skip to content

Commit

Permalink
fix: catch econnreset errors (#247)
Browse files Browse the repository at this point in the history
* fix: catch econnreset errors

* fix: also on images
  • Loading branch information
rafaelcr authored Aug 26, 2024
1 parent 664f39a commit 51347d6
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/token-processor/images/image-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from '../util/errors';
import { pipeline } from 'node:stream/promises';
import { Storage } from '@google-cloud/storage';
import { RetryableJobError } from '../queue/errors';

/** Saves an image provided via a `data:` uri string to disk for processing. */
function convertDataImage(uri: string, tmpPath: string): string {
Expand Down Expand Up @@ -156,6 +157,9 @@ export async function processImageCache(
if (typeError.cause instanceof errors.ResponseExceededMaxSizeError) {
throw new ImageSizeExceededError(`ImageCache image too large: ${imgUrl}`);
}
if ((typeError.cause as any).toString().includes('ECONNRESET')) {
throw new RetryableJobError(`ImageCache server connection interrupted`, typeError);
}
}
throw error;
}
Expand Down
6 changes: 6 additions & 0 deletions src/token-processor/util/metadata-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
MetadataSizeExceededError,
MetadataTimeoutError,
TooManyRequestsHttpError,
UndiciCauseTypeError,
} from './errors';
import { RetryableJobError } from '../queue/errors';
import { normalizeImageUri, processImageCache } from '../images/image-cache';
Expand Down Expand Up @@ -263,6 +264,11 @@ export async function fetchMetadata(httpUrl: URL): Promise<string | undefined> {
throw new MetadataSizeExceededError(url);
} else if (error instanceof errors.ResponseStatusCodeError && error.statusCode === 429) {
throw new TooManyRequestsHttpError(httpUrl, error);
} else if (
error instanceof TypeError &&
((error as UndiciCauseTypeError).cause as any).toString().includes('ECONNRESET')
) {
throw new RetryableJobError(`Server connection interrupted`, error);
}
throw new MetadataHttpError(`${url}: ${error}`, error);
}
Expand Down
25 changes: 19 additions & 6 deletions tests/token-queue/metadata-helpers.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { MockAgent, setGlobalDispatcher } from 'undici';
import { ENV } from '../../src/env';
import {
MetadataHttpError,
MetadataParseError,
MetadataSizeExceededError,
MetadataTimeoutError,
} from '../../src/token-processor/util/errors';
import { MetadataHttpError } from '../../src/token-processor/util/errors';
import {
getFetchableDecentralizedStorageUrl,
getMetadataFromUri,
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 () => {
Expand Down Expand Up @@ -217,4 +213,21 @@ describe('Metadata Helpers', () => {
'https://ipfs.io/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn/7-es.json'
);
});

test('catches ECONNRESET errors', async () => {
const url = new URL('http://test.io/1.json');
const agent = new MockAgent();
agent.disableNetConnect();
agent
.get('http://test.io')
.intercept({
path: '/1.json',
method: 'GET',
})
// Simulate the weird error thrown by Undici.
.replyWithError(Object.assign(new TypeError(), { cause: new Error('read ECONNRESET') }));
setGlobalDispatcher(agent);

await expect(fetchMetadata(url)).rejects.toThrow(RetryableJobError);
});
});

0 comments on commit 51347d6

Please sign in to comment.