From 6d528113fe8a39a0bf39245888c38cdb858b183a Mon Sep 17 00:00:00 2001 From: Daniel Padrino Date: Wed, 22 Jul 2026 21:28:33 -0300 Subject: [PATCH 1/2] 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 sentToFallback compared operation.getContext().targetUrl against CONFIG.indexerFallback by string value. Once an operator points the fallback at the same host as the primary (the documented way to get CONFIG_INDEXER_FALLBACK_URL populated without cross-environment failover, see the prd/dev compose files), that 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. Confirmed live: 30/30 recent ApiApolloConfig network-error log lines in prod were at error, none at warn, despite the fallback fix (#117/#121) being deployed since 2026-07-20. 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 From 715e47244f657d2a0d047dff2a88b2915d5e1a92 Mon Sep 17 00:00:00 2001 From: Daniel Padrino Date: Wed, 22 Jul 2026 21:38:20 -0300 Subject: [PATCH 2/2] fix: avoid internal hostname-shorthand wording in comment "prd/dev" echoes internal server naming shorthand that doesn't belong in a public repo; reword to a generic reference. --- api.apollo.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.apollo.config.ts b/api.apollo.config.ts index c019cd0..459421e 100644 --- a/api.apollo.config.ts +++ b/api.apollo.config.ts @@ -29,7 +29,7 @@ function activateFallback(): void { // 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). +// failover; see CONFIG_INDEXER_FALLBACK_URL in this repo's own deploy config). const routingLink = new ApolloLink((operation, forward) => { operation.setContext({ targetUrl: getIndexerUrl(), usedFallback: isFallbackActive() }); return forward(operation);