Handle partial data and error paths - #926
Open
hugo-vrijswijk wants to merge 1 commit into
Open
Conversation
This is a complicated change, and open to discussion if it is actually wanted.
Failed fields now propagate their `null` to the nearest nullable position, rather than a `Result.Failure` which discards all data. Example:
Before:
```graphql
query {
ping
viaEffect {
name
}
}
{
"errors": [
{ "message": "boom" }
]
}
```
After:
```graphql
query {
ping
viaEffect {
name
}
}
{
"data": {
"ping": "pong",
"viaEffect": null
},
"errors": [
{ "message": "boom", "path": ["viaEffect"] }
]
}
```
This is a big breaking change for users that expect data to be complete if there is `data` at the root. But it is in line with the GraphQL specification, which says that a failed field should not discard its siblings' data. This partially closes a few conformance suites, except for `location`s in errors, which are not (yet) implemented.
---
The interpreter now tracks the response position of each value:
- A failure at a nullable position completes as null and keeps the data of its siblings.
- A failure at a non-null position propagates its null to the nearest enclosing nullable position.
- A null which reaches the root leaves `data` as null.
Each problem carries the response path of its own position, with the alias of the field and the index of the list entry.
Both error policies now complete the deferred positions of a failed batch as null and keep the rest of the response. An internal error stays a request error and aborts the completion.
BREAKING: `Problem.path` changes type from `List[String]` to `List[Problem.PathSegment]`, so that a path can hold list indexes. A segment is a `Name(String)` or an `Index(Int)`.
hugo-vrijswijk
force-pushed
the
fix/field-error-path-and-null-propagation
branch
from
August 31, 2026 21:56
78fc852 to
9557888
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a complicated change, and open to discussion if it is actually wanted.
Failed fields now propagate their
nullto the nearest nullable position, rather than aResult.Failurewhich discards all data. Example:Before:
After:
More examples are in the tests, which show the difference clearly. This is a big breaking change for users that expect data to be complete if there is
dataat the root. Release notes should mention this very clearly. But it is in line with the GraphQL specification, which says that a failed field should not discard its siblings' data. This partially closes a few conformance suites, except forlocations in errors, which are not (yet) implemented.The interpreter now tracks the response position of each value:
dataas null.Each problem carries the response path of its own position, with the alias of the field and the index of the list entry.
Both error policies now complete the deferred positions of a failed batch as null and keep the rest of the response. An internal error stays a request error and aborts the completion.
BREAKING:
Problem.pathchanges type fromList[String]toList[Problem.PathSegment], so that a path can hold list indexes. A segment is aName(String)or anIndex(Int).