From ea723f0a515b1ba3be697c3b92f03710883871c8 Mon Sep 17 00:00:00 2001 From: tilacog Date: Mon, 9 Oct 2023 17:06:59 -0300 Subject: [PATCH] common: harden freshness subgraph queries and fix recursion bug - refine subgraph query result shape validation - account for error property named 'errors' and 'error' - pass 'variables' value when recursing --- packages/indexer-common/src/subgraphs.ts | 50 ++++++++++++++++++++---- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/packages/indexer-common/src/subgraphs.ts b/packages/indexer-common/src/subgraphs.ts index c0e3acd46..f06e03bd0 100644 --- a/packages/indexer-common/src/subgraphs.ts +++ b/packages/indexer-common/src/subgraphs.ts @@ -442,18 +442,26 @@ export class SubgraphFreshnessChecker { ]) // Return it early if query results contains errors - if (subgraphQueryResult.errors) { + if (subgraphQueryResult.errors || subgraphQueryResult.error) { return subgraphQueryResult } - const latestIndexedBlock = subgraphQueryResult?.data?._meta?.block?.number - if (!latestIndexedBlock) { - const errorMsg = `Failed to infer block number for ${this.subgraphName} query` - this.logger.error(errorMsg, { query: print(updatedQuery) }) - // Check for unexpected missing block data as a precaution. + // Check for missing block metadata + const queryShapeError = this.checkMalformedQueryResult(subgraphQueryResult) + if (queryShapeError) { + const errorMsg = `Failed to infer block number for ${this.subgraphName} query: ${queryShapeError}` + this.logger.error(errorMsg, { + query: print(updatedQuery), + subgraph: this.subgraphName, + error: queryShapeError, + subgraphQueryResult, + }) throw new Error(errorMsg) } + // At this point we have validated that this value exists and is numeric. + const latestIndexedBlock: number = subgraphQueryResult.data._meta.block.number + // Check subgraph freshness const blockDistance = latestNetworkBlock - latestIndexedBlock const logInfo = { @@ -479,10 +487,38 @@ export class SubgraphFreshnessChecker { logInfo, ) await sleep(this.sleepDurationMillis) - return this.checkedQueryRecursive(updatedQuery, subgraph, retriesLeft - 1) + return this.checkedQueryRecursive( + updatedQuery, + subgraph, + retriesLeft - 1, + variables, + ) } else { this.logger.trace(`${this.subgraphName} is fresh`, logInfo) } return subgraphQueryResult } + + // Checks if the query result has the expecte + // eslint-disable-next-line @typescript-eslint/no-explicit-any + checkMalformedQueryResult(subgraphQueryResult: any): string | undefined { + if (!subgraphQueryResult) { + return 'Subgraph query result is null or undefined' + } + if (!subgraphQueryResult.data) { + return 'Subgraph query data is null or undefined' + } + if (!subgraphQueryResult.data._meta) { + return 'Query metadata is null or undefined' + } + if (!subgraphQueryResult.data._meta.block) { + return 'Block metadata is null or undefined' + } + if ( + !subgraphQueryResult.data._meta.block.number && + typeof subgraphQueryResult.data._meta.block.number === 'number' + ) { + return 'Block number is null or undefined' + } + } }