From 54e410f1ccac45b9245cd4bf1badf37260acce7c Mon Sep 17 00:00:00 2001 From: Daniel Padrino Date: Fri, 24 Jul 2026 15:52:07 -0300 Subject: [PATCH] Retry transient Ponder GraphQL network errors The GetPositionsV2 sync job occasionally sees a "Premature close" from the indexer, consistent with a stale keep-alive socket being reused right as it's closed server-side. There was no retry for this case: network errors that couldn't fall back landed straight in the logs. Adds a RetryLink ahead of the HTTP link so transport-level failures get a few short, jittered retries before reaching the error/fallback handling. GraphQL-level errors are unaffected. --- api.apollo.config.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/api.apollo.config.ts b/api.apollo.config.ts index c2af9ef..6be4354 100644 --- a/api.apollo.config.ts +++ b/api.apollo.config.ts @@ -1,5 +1,6 @@ import { ApolloClient, ApolloLink, createHttpLink, InMemoryCache } from '@apollo/client/core'; import { onError } from '@apollo/client/link/error'; +import { RetryLink } from '@apollo/client/link/retry'; import { Logger } from '@nestjs/common'; import fetch from 'cross-fetch'; import { CONFIG } from './api.config'; @@ -57,6 +58,14 @@ const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) } }); +// Retries transport-level failures (e.g. a stale keep-alive socket closing +// mid-response) before they reach errorLink, so a one-off blip self-heals +// instead of tripping the fallback/error path. +const retryLink = new RetryLink({ + delay: { initial: 200, max: 2000, jitter: true }, + attempts: { max: 3, retryIf: (error) => !!error }, +}); + const httpLink = createHttpLink({ uri: (operation) => operation.getContext().targetUrl ?? getIndexerUrl(), fetch: (uri: RequestInfo | URL, options?: RequestInit) => { @@ -74,7 +83,7 @@ const httpLink = createHttpLink({ }, }); -const link = ApolloLink.from([errorLink, routingLink, httpLink]); +const link = ApolloLink.from([errorLink, routingLink, retryLink, httpLink]); export const PONDER_CLIENT = new ApolloClient({ link,