Skip to content

Commit

Permalink
fix: handle indexer-service error format (#896)
Browse files Browse the repository at this point in the history
The gateway has been failing to provide indexer errors to consumers
(just saying `no attestation`) in some cases because indexer-service is
deviating from the expectations of [GraphQL over
HTTP](https://graphql.org/learn/serving-over-http/#response). Instead of
putting errors in the `errors`, it's using an `error` field. For
example: `{"error": "GraphQL server error (client error): Invalid query
variables provided"}`
  • Loading branch information
Theodus authored Jul 22, 2024
1 parent cf17da8 commit d99f556
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions graph-gateway/src/indexer_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use thegraph_core::types::{
attestation::{self, Attestation},
DeploymentId,
};
use thegraph_graphql_http::http::response::{Error as GQLError, ResponseBody as GQLResponseBody};
use thegraph_graphql_http::http::response::Error as GQLError;
use url::Url;

use crate::{receipts::Receipt, unattestable_errors::miscategorized_unattestable};
Expand Down Expand Up @@ -151,6 +151,17 @@ impl IndexerClient {
fn rewrite_response(
response: &str,
) -> Result<(String, Vec<GQLError>, Option<Block>), IndexerError> {
#[derive(Deserialize, Serialize)]
struct Response {
data: Option<ProbedData>,
#[serde(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
errors: Vec<GQLError>,
// indexer-service sometimes returns errors in this form, which isn't ideal
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
error: Option<String>,
}
#[derive(Deserialize, Serialize)]
struct ProbedData {
#[serde(rename = "_gateway_probe_", skip_serializing)]
Expand All @@ -168,9 +179,17 @@ fn rewrite_response(
hash: BlockHash,
timestamp: Option<u64>,
}
let mut payload: GQLResponseBody<ProbedData> =
let mut payload: Response =
serde_json::from_str(response).map_err(|err| BadResponse(err.to_string()))?;

if let Some(err) = payload.error.take() {
payload.errors.push(GQLError {
message: err,
locations: Default::default(),
path: Default::default(),
});
}

// Avoid processing oversized errors.
for err in &mut payload.errors {
err.message.truncate(256);
Expand Down

0 comments on commit d99f556

Please sign in to comment.