Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Query Validation Errors with Detailed Context Information #4223

Open
Tracked by #4168
spellew opened this issue Nov 16, 2023 · 3 comments
Open
Tracked by #4168

Enhance Query Validation Errors with Detailed Context Information #4223

spellew opened this issue Nov 16, 2023 · 3 comments

Comments

@spellew
Copy link

spellew commented Nov 16, 2023

Query validation errors currently lack context about the location of the error (e.g., object type, field, argument, and element). This makes it more difficult to debug issues, especially in larger queries.

Describe the solution you'd like
I propose enhancing the error messages to include details about where the error occurred. For example, instead of the current message, "Expected value of type "Int!", found null.", the error could be more informative like "Expected value of type "Int!", found null at Query.topUsers, argument 'first[1]'.".

Additional context
Steps to Reproduce:

  • Run the following test code.
  • Observe the error message when a null value is passed where an integer is expected.
use apollo_router::services::supergraph;
use apollo_router::TestHarness;
use tower::{BoxError, ServiceExt};

#[tokio::test]
async fn test_query_validation_error() -> Result<(), BoxError> {
    let test_service = TestHarness::builder()
        .schema("
            schema
                @core(feature: \"https://specs.apollo.dev/core/v0.1\")
                @core(feature: \"https://specs.apollo.dev/join/v0.1\")
            {
              query: Query
            }

            directive @core(feature: String!) repeatable on SCHEMA
            directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet) on FIELD_DEFINITION
            directive @join__type(graph: join__Graph!, key: join__FieldSet) repeatable on OBJECT | INTERFACE
            directive @join__owner(graph: join__Graph!) on OBJECT | INTERFACE
            directive @join__graph(name: String!, url: String!) on ENUM_VALUE
            scalar join__FieldSet

            type Query {
              topUsers(first: [Int!]): [User]
            }

            enum join__Graph {
                ACCOUNTS @join__graph(name: \"accounts\" url: \"http://localhost:4001\")
            }

            type User @join__owner(graph: ACCOUNTS) {
              id: ID!
              name: String
            }
        ")
        .build_supergraph()
        .await?;

    let request = supergraph::Request::fake_builder()
        .query("query TopUsers {
            topUsers(first: [1, null]) {
                name
            }
        }")
        .build()
        .unwrap();

    let mut supergraph_response = test_service.oneshot(request).await?;
    let gql_response = supergraph_response.next_response().await.unwrap();

    Err(BoxError::from(format!("{:?}", gql_response.errors.get(0).unwrap().message)))
}
@SimonSapin
Copy link
Contributor

Hi! Are these steps based on a modified version of the Router? I didn’t find a set_into_graphql_errors function or RouterError enum in the repository or its history.

By removing that import and call I can reproduce. Removing .message on the last line also shows the rest of the error JSON object:

Error: "Error { message: \"Expected value of type \\\"Int!\\\", found null.\", locations: [], path: None, extensions: {\"code\": String(\"GRAPHQL_VALIDATION_FAILED\")} }"

This shows another bug: location is an empty array but should contain one entry with a line and column number pointing to the offending null value.

As to the message, it comes from validation code in graphql-js. We’re in the process of replacing this with a new Rust implementation of validation, and as part of that want to improve messages. For example apollographql/apollo-rs#757 is for schemas rather than operations but is in the same spirit as your suggestion.

@spellew
Copy link
Author

spellew commented Nov 27, 2023

Hi, I've removed the modified code. Is there a tracker or roadmap that details all of the components being replaced in graphql-js?

@SimonSapin
Copy link
Contributor

I’m not sure we have a single place that properly tracks it all at a high level, but one goal is to remove Deno/V8 from the Router so we’re actively working on Rust replacements for every TypeScript components. Off the top of my head, the major ones are validation, query planning, schema introspection, extracting an API schema from a supergraph schema, and generating the "signature" (normalize then hash) of an operation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants