Skip to content

Commit 4cde353

Browse files
committed
Directive proposal for opting out of null bubbling
1 parent 69cab2a commit 4cde353

File tree

1 file changed

+95
-1
lines changed

1 file changed

+95
-1
lines changed

spec/Section 3 -- Type System.md

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2025,7 +2025,8 @@ by a validator, executor, or client tool such as a code generator.
20252025

20262026
:: A _built-in directive_ is any directive defined within this specification.
20272027

2028-
GraphQL implementations should provide the `@skip` and `@include` directives.
2028+
GraphQL implementations should provide the `@skip`, `@include` and
2029+
`@nullOnError` directives.
20292030

20302031
GraphQL implementations that support the type system definition language must
20312032
provide the `@deprecated` directive if representing deprecated portions of the
@@ -2247,3 +2248,96 @@ to the relevant IETF specification.
22472248
```graphql example
22482249
scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122")
22492250
```
2251+
2252+
### @nullOnError
2253+
2254+
```graphql
2255+
directive @nullOnError on QUERY | MUTATION | SUBSCRIPTION
2256+
```
2257+
2258+
The `@nullOnError` _built-in directive_ may be provided on query, mutation and
2259+
subscription operations, and disables the error propagation behavior described
2260+
in [Handling Field Errors](#sec-Handling-Field-Errors) by treating all Non-Null
2261+
types as if they were instead Null-Only-On-Error types.
2262+
2263+
Note: This is useful for clients that still wish to receive sibling fields when
2264+
an error on a Non-Null value occurs. Effectively, `@nullOnError` enables the
2265+
client to opt in to handling errors locally; for example, a client might use
2266+
this to limit the scope of null propagation to a fragment rather than the entire
2267+
field, or to update a normalized store even when an error occurs.
2268+
2269+
Consider the following schema:
2270+
2271+
```graphql
2272+
type Query {
2273+
me: Viewer
2274+
}
2275+
2276+
type Viewer {
2277+
username: String!
2278+
bestFriend: Viewer!
2279+
}
2280+
```
2281+
2282+
If the `bestFriend` field were to return `null`, then the following operation:
2283+
2284+
```graphql example
2285+
query myQuery {
2286+
me {
2287+
username
2288+
bestFriend {
2289+
username
2290+
}
2291+
}
2292+
}
2293+
```
2294+
2295+
Would return a result such as:
2296+
2297+
```json example
2298+
{
2299+
"errors": [
2300+
{
2301+
"message": "Value cannot be null",
2302+
"locations": [{ "line": 4, "column": 5 }],
2303+
"path": ["me", "bestFriend"]
2304+
}
2305+
],
2306+
"data": {
2307+
"me": null
2308+
}
2309+
}
2310+
```
2311+
2312+
However, if we apply the `@nullOnError` directive to our operation:
2313+
2314+
```graphql example
2315+
query myQuery @nullOnError {
2316+
me {
2317+
username
2318+
bestFriend {
2319+
username
2320+
}
2321+
}
2322+
}
2323+
```
2324+
2325+
The result would contain identical errors, but the "me" field will be populated:
2326+
2327+
```json example
2328+
{
2329+
"errors": [
2330+
{
2331+
"message": "Value cannot be null",
2332+
"locations": [{ "line": 4, "column": 5 }],
2333+
"path": ["me", "bestFriend"]
2334+
}
2335+
],
2336+
"data": {
2337+
"me": {
2338+
"username": "billy",
2339+
"bestFriend": null
2340+
}
2341+
}
2342+
}
2343+
```

0 commit comments

Comments
 (0)