Skip to content

[RFC] Value Completion: Improved Error Path for Lists Of Objects #595

@SoyYoRafa

Description

@SoyYoRafa

Problem

I would like to raise an issue with error paths and lists of objects during value completion. The goal is to speed up the debugging and resolution of server-side data issues which are raised during execution value completion by improving error paths.

Consider the following schema:

type Query {
  MyObjects: [MyObject!]!
}
type MyObject {
  key: ID!
  aFloat: Float!
  ... additional fields
}

Currently, if there is a data issue during value completion with fields in MyObject, the error path is ["MyObjects", idx, field] (e.g. ["MyObjects", 0, "aFloat"]). A data issue could be that aFloat is null in some object but the schema declares it as non-null. We want to know which element in MyObjects has the issue. Using an index has limitations for two different reasons:

  1. It is not the most helpful. We have to be able to inspect the result set outside of GraphQL in order to determine which specific object had the issue. By not knowing the key, we need to an additional step to figure out which object has the error.
  2. The index is only useful if the list order is deterministic. We are often operating with scalable, distributed systems. If a query is serviced by multiple nodes in a distributed system, the result set is highly likely to not have a deterministic order. If the result set does not have a deterministic order, the index is effectively meaningless. People may claim that the MyObjects resolver can just sort the result. In my opinion, the biggest issue with that is that when we have to inspect the result set outside of GraphQL we would have to manually sort again the result set. This is pretty painful to do in a during a production issue. Finally, we would have to incur the cost of sorting.

Proposal

I would like to propose a new directive that would indicate that the field, if present, should be included in the error path. The directive could be applied to zero or more fields in an object. An stringified object would be added to the path with the fields name and values that contain the directive. I don't really care about the name but for illustration purposes, let's call it @addpath:

type Query {
  MyObjects: [MyObject!]!
}
type MyObject {
  key: ID! @addpath
  aFloat: Float!
  ... additional fields
}

The path created would then be either of the following.

  1. A append ["MyObjects", idx, "{key: ...}", field]
  2. A replace ["MyObjects", "{key: ...}", field]

I suspect the append would be cleaner to implement and it keeps the index in case anyone wants both. This proposal is not intrusive to developers who don't want to pay the cost of the object construction and it is an opt-in feature.

Metadata

Metadata

Assignees

No one assigned

    Labels

    💤 stale ?This issue/PR has not been updated in more than 1 year and is not actionable anymore.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions