diff --git a/api.apollo.config.ts b/api.apollo.config.ts index 2d262bf..9f7198b 100644 --- a/api.apollo.config.ts +++ b/api.apollo.config.ts @@ -6,23 +6,22 @@ import { CONFIG } from './api.config'; const logger = new Logger('ApiApolloConfig'); -// Fallback URL management let fallbackUntil: number | null = null; function getIndexerUrl(): string { - if (fallbackUntil && Date.now() < fallbackUntil) return CONFIG.indexerFallback; - if (fallbackUntil) fallbackUntil = null; // Reset expired fallback - return CONFIG.indexer; + return fallbackUntil && Date.now() < fallbackUntil + ? CONFIG.indexerFallback + : CONFIG.indexer; } function activateFallback(): void { if (!fallbackUntil) { - fallbackUntil = Date.now() + 10 * 60 * 1000; // 10 minutes + fallbackUntil = Date.now() + 10 * 60 * 1000; logger.log(`[Ponder] Switching to fallback for 10min: ${CONFIG.indexerFallback}`); } } -const errorLink = onError(({ graphQLErrors, networkError, operation }) => { +const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => { if (graphQLErrors) { graphQLErrors.forEach((error) => { logger.error(`[GraphQL error in operation: ${operation?.operationName || 'unknown'}]`, { @@ -32,6 +31,7 @@ const errorLink = onError(({ graphQLErrors, networkError, operation }) => { }); }); } + if (networkError) { logger.error(`[Network error in operation: ${operation?.operationName || 'unknown'}]`, { message: networkError.message, @@ -39,28 +39,35 @@ const errorLink = onError(({ graphQLErrors, networkError, operation }) => { stack: networkError.stack, }); - // Activate fallback on network errors - if (getIndexerUrl() === CONFIG.indexer) activateFallback(); + if (getIndexerUrl() === CONFIG.indexer) { + const is503 = + (networkError as any)?.response?.status === 503 || + (networkError as any)?.statusCode === 503 || + (networkError as any)?.result?.status === 503; + + if (is503) { + logger.log('[Ponder] 503 Service Unavailable - Ponder is syncing, switching to fallback'); + } else { + logger.log('[Ponder] Network error detected, activating fallback'); + } + activateFallback(); + return forward(operation); + } } }); const httpLink = createHttpLink({ - uri: getIndexerUrl, + uri: () => getIndexerUrl(), fetch: (uri: RequestInfo | URL, options?: RequestInit) => { const controller = new AbortController(); const timeout = setTimeout(() => { controller.abort(); - }, 10000); // 10 second timeout + }, 10000); return fetch(uri, { ...options, signal: controller.signal, }) - .catch((error) => { - // Activate fallback on http errors - if (getIndexerUrl() === CONFIG.indexer) activateFallback(); - throw error; - }) .finally(() => { clearTimeout(timeout); }); diff --git a/ecosystem/ecosystem.minter.service.ts b/ecosystem/ecosystem.minter.service.ts index edbf357..1272ba2 100644 --- a/ecosystem/ecosystem.minter.service.ts +++ b/ecosystem/ecosystem.minter.service.ts @@ -86,14 +86,14 @@ export class EcosystemMinterService { return list; } - async getRecentMints(timestamp: Date, minValue: bigint): Promise { + async getRecentMintsFromPositions(timestamp: Date, minValue: bigint): Promise { const checkTimestamp = Math.trunc(timestamp.getTime() / 1000); const mintsFetched = await PONDER_CLIENT.query({ fetchPolicy: 'no-cache', query: gql` query { - mints( + positionMints( orderBy: "timestamp", orderDirection: "desc" where: { timestamp_gt: "${checkTimestamp}" @@ -111,6 +111,6 @@ export class EcosystemMinterService { } `, }); - return mintsFetched?.data?.mints?.items ?? []; + return mintsFetched?.data?.positionMints?.items ?? []; } } diff --git a/socialmedia/socialmedia.service.ts b/socialmedia/socialmedia.service.ts index 61adead..2dd8a84 100644 --- a/socialmedia/socialmedia.service.ts +++ b/socialmedia/socialmedia.service.ts @@ -169,7 +169,7 @@ export class SocialMediaService { const checkDate = new Date(this.socialMediaState.mintUpdates); const minAmount = BigInt(MIN_MINTING_AMOUNT * 10 ** 18); - const requestedMints = await this.mints.getRecentMints(checkDate, minAmount); + const requestedMints = await this.mints.getRecentMintsFromPositions(checkDate, minAmount); if (requestedMints.length > 0) { this.socialMediaState.mintUpdates = Date.now();