From 809ff2ef17ac28cee8eb02269634ac829da367c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Dumas?= Date: Sun, 2 Apr 2023 16:22:15 -0400 Subject: [PATCH 1/2] throw errors on specific graphql error messages --- packages/indexer-service/src/queries.ts | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/packages/indexer-service/src/queries.ts b/packages/indexer-service/src/queries.ts index 931796880..168ee989e 100644 --- a/packages/indexer-service/src/queries.ts +++ b/packages/indexer-service/src/queries.ts @@ -95,6 +95,37 @@ export class QueryProcessor implements QueryProcessorInterface { this.receiptManager = receiptManager } + validateResponse(query: String, response: AxiosResponse, ipfsHash: String): void { + // Check response for specific graphql errors + const throwableErrors = [ + 'Failed to decode `block.hash` value: `no block with that hash found`', + 'Store error: database unavailable', + 'Store error: store error: Fulltext search is not yet deterministic' + ] + + // Optimization: Parse only if the message is small enough, presume there are no critical errors otherwise + if (response.data.length > 500) { + return + } + + const responseData = JSON.parse(response.data); + if (responseData.errors) { + this.logger.debug('GraphQL errors', { + deployment: ipfsHash, + errors: responseData.errors, + query, + }) + for (const graphqlError of responseData.errors) { + if (throwableErrors.includes(graphqlError.message)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const error = Error(graphqlError.message) as any + error.status = 500; + throw error; + } + } + } + } + async executeFreeQuery(query: FreeQuery): Promise> { const { subgraphDeploymentID } = query @@ -104,6 +135,8 @@ export class QueryProcessor implements QueryProcessorInterface { query.query, ) + this.validateResponse(query.query, response, subgraphDeploymentID.ipfsHash) + return { status: 200, result: { @@ -145,6 +178,8 @@ export class QueryProcessor implements QueryProcessorInterface { throw error } + this.validateResponse(query, response, subgraphDeploymentID.ipfsHash) + let attestation = null if (response.headers['graph-attestable'] == 'true') { attestation = await signer.createAttestation(query, response.data) From 6613101e0da2de1c1361ca657086c32f336ac5d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Dumas?= Date: Thu, 13 Apr 2023 14:11:00 -0400 Subject: [PATCH 2/2] expand throwable error list --- packages/indexer-service/src/queries.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/indexer-service/src/queries.ts b/packages/indexer-service/src/queries.ts index 168ee989e..e113a1da9 100644 --- a/packages/indexer-service/src/queries.ts +++ b/packages/indexer-service/src/queries.ts @@ -98,9 +98,10 @@ export class QueryProcessor implements QueryProcessorInterface { validateResponse(query: String, response: AxiosResponse, ipfsHash: String): void { // Check response for specific graphql errors const throwableErrors = [ - 'Failed to decode `block.hash` value: `no block with that hash found`', + 'Failed to decode `block.hash` value:', 'Store error: database unavailable', - 'Store error: store error: Fulltext search is not yet deterministic' + 'Store error: store error: Fulltext search is not yet deterministic', + 'Failed to decode `block.number` value:' ] // Optimization: Parse only if the message is small enough, presume there are no critical errors otherwise @@ -116,7 +117,10 @@ export class QueryProcessor implements QueryProcessorInterface { query, }) for (const graphqlError of responseData.errors) { - if (throwableErrors.includes(graphqlError.message)) { + const isThrowableError = throwableErrors.some((errorString) => + graphqlError.message.startsWith(errorString) + ); + if (isThrowableError) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const error = Error(graphqlError.message) as any error.status = 500;