Skip to content

Add more details to static errors raised after the query run #5241

Open
@sobrinho

Description

@sobrinho

Is your feature request related to a problem? Please describe.

Static errors that makes the query invalid points straight to the error location, i.e.:

{
  "errors": [
    {
      "message": "Field 'documents' is missing required arguments: kind",
      "locations": [
        {
          "line": 7,
          "column": 7
        }
      ],
      "path": [
        "query",
        "employees",
        "documents",
        "kind"
      ]
    }
  ]
}

But static errors such as non-nullable field does not, i.e.:

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field Employee.status"
    }
  ]
}

The problem is that it makes really hard to debug since you can have a query that return multiple nodes such as:

query {
  employees {
    id
    fullName
    status
  }
}

If you have 100 employees, which one did return an empty status?

Describe the solution you'd like

Would be nice to have the error wrapped pointing to the specific object that failed the validation, i.e.:

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field Employee.status",
      "object": {
        "wrapping_type": "EmployeeType",
        "type": "Employee",
        "gid": "..."
      }
    }
  ]
}

Describe alternatives you've considered

We built a GraphQL::Schema::FieldExtension to add this context to unhandled exceptions but it doesn't trigger for static errors.

Be aware of the two kinds of static errors: on the query (missing argument, undefined field) and on the result (non-nullable fields).

While the first one doesn't have a backtrace, it does show the line and column on the query and the path.

The second one doesn't have a backtrace and points to the type/field that failed but not the object or a backtrace.

Could be interesting to have the backtrace as well like:

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field Employee.status",
      "object": {
        "wrapping_type": "EmployeeType",
        "type": "Employee",
        "gid": "..."
      },
      "location": ["/app/types/employee_type.rb", 15]
    }
  ]
}

Probably the location is not trackable in all scenarios like when the object is a Hash, but we could have something designed for the other kinds where the field is not implemented on the type:

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field Employee.status",
      "object": {
        "wrapping_type": "EmployeeType",
        "type": "Hash",
        "value": { "id": "...", "status": "" }
      },
      "location": null
    }
  ]
}

Additional context

While this extremely useful for debugging, it might leak important data if misused and rendered to the user.

What I'm thinking of is that those information would be added to data.query.static_errors and data.context.errors or conditionally rendered if the Rails.env is development or test.

Alternatively, it could be a feature flag or a use GraphQL::DetailedStaticErrors unless Rails.env.production?.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions