From b5e0b21f686d7157690bcec3d1268a116f7d6f43 Mon Sep 17 00:00:00 2001 From: Daniel Padrino Date: Wed, 22 Jul 2026 21:29:14 -0300 Subject: [PATCH] fix: track Ponder fallback routing as a flag, not a URL comparison MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ported from d-EURO/api#123. sentToFallback compared the request's targetUrl against CONFIG.indexerFallback by string value. Our compose files (dfxprd + dfxdev) set CONFIG_INDEXER_FALLBACK_URL to the same host as CONFIG_INDEXER_URL — the only way to keep the var populated without cross-environment failover. With primary and fallback string-identical, the comparison is true on every request regardless of which URL it actually went to, so the warn+retry branch never fires and every network error still falls through to logger.error. Stamp the routing decision itself (isFallbackActive() at send time) instead of re-deriving it from a URL string. --- api.apollo.config.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/api.apollo.config.ts b/api.apollo.config.ts index c2af9ef..c019cd0 100644 --- a/api.apollo.config.ts +++ b/api.apollo.config.ts @@ -24,10 +24,14 @@ function activateFallback(): void { } } -// Stamps each attempt with its target URL so errors are attributed to the URL -// the request was actually sent to, not the routing state at error time. +// Stamps each attempt with the URL it was sent to and whether that was the +// fallback, so errors are attributed to the routing state at SEND time, not +// re-derived from the URL at error time — a bare URL comparison can't tell +// primary from fallback once an operator points the fallback at the same +// host as the primary (the standard way to disable cross-environment +// failover; see CONFIG_INDEXER_FALLBACK_URL in the prd/dev compose files). const routingLink = new ApolloLink((operation, forward) => { - operation.setContext({ targetUrl: getIndexerUrl() }); + operation.setContext({ targetUrl: getIndexerUrl(), usedFallback: isFallbackActive() }); return forward(operation); }); @@ -42,7 +46,7 @@ const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) if (networkError) { const msg = `[Network error in operation: ${opName}] ${networkError.message}`; - const sentToFallback = !!CONFIG.indexerFallback && operation.getContext().targetUrl === CONFIG.indexerFallback; + const sentToFallback = !!operation.getContext().usedFallback; if (CONFIG.indexerFallback && !sentToFallback) { // Primary failed and a fallback exists — log at warn so transparent