From 72d41839c0c22d4262c3e7da5ae3df7c47c5768c Mon Sep 17 00:00:00 2001 From: Danswar <48102227+Danswar@users.noreply.github.com> Date: Sat, 25 Jul 2026 14:36:01 -0300 Subject: [PATCH] Retry transient Ponder GraphQL network errors (#125) 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. The existing fallback path only retries when the fallback URL differs from the primary, and in this deployment they're intentionally the same host, so every occurrence went straight to the logs with nothing more attempted. Adds a RetryLink ahead of the HTTP link so transport-level failures get a few short, jittered retries before reaching the error/fallback handling, independent of how primary/fallback are configured. 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,