From d893515b932608ea08c9c6e90b83f340e40f6f8e Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Fri, 26 Jun 2026 21:00:06 +0200 Subject: [PATCH] fix: catch individual repo fetch failures to prevent batch crashes Wrap each repository fetch in try/catch so one failure (Redis, network, etc.) doesn't crash the entire query batch. Failed repos now return a proper error response instead of causing all repos to show "No response from provider". --- packages/api/src/router/widgets/releases.ts | 46 +++++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/packages/api/src/router/widgets/releases.ts b/packages/api/src/router/widgets/releases.ts index ac56e3ec5..fab3abac7 100644 --- a/packages/api/src/router/widgets/releases.ts +++ b/packages/api/src/router/widgets/releases.ts @@ -77,26 +77,36 @@ export const releasesRouter = createTRPCRouter({ return await Promise.all( input.repositories.map(async (repository) => { - const useToken = allowedRepoIds === null || allowedRepoIds.has(repository.id); - const response = await releasesRequestHandler - .handler({ + try { + const useToken = allowedRepoIds === null || allowedRepoIds.has(repository.id); + const response = await releasesRequestHandler + .handler({ + id: repository.id, + provider: repository.provider, + identifier: repository.identifier, + versionRegex: formatVersionFilterRegex(repository.versionFilter), + providerUrl: repository.providerUrl, + token: useToken ? tokensByProvider.get(repository.provider) : undefined, + }) + .getCachedOrUpdatedDataAsync({ + forceUpdate: false, + }); + + return { id: repository.id, provider: repository.provider, - identifier: repository.identifier, - versionRegex: formatVersionFilterRegex(repository.versionFilter), - providerUrl: repository.providerUrl, - token: useToken ? tokensByProvider.get(repository.provider) : undefined, - }) - .getCachedOrUpdatedDataAsync({ - forceUpdate: false, - }); - - return { - id: repository.id, - provider: repository.provider, - timestamp: response.timestamp, - ...response.data, - }; + timestamp: response.timestamp, + ...response.data, + }; + } catch (error) { + return { + id: repository.id, + provider: repository.provider, + timestamp: new Date(), + success: false as const, + error: { code: "unexpected" as const, message: String(error) }, + }; + } }), ); }),