Skip to content

Commit e58ab2b

Browse files
committed
Directive proposal for opting out of null bubbling
1 parent 23fa23b commit e58ab2b

File tree

1 file changed

+95
-1
lines changed

1 file changed

+95
-1
lines changed

spec/Section 3 -- Type System.md

+95-1
Original file line numberDiff line numberDiff line change
@@ -2018,7 +2018,8 @@ by a validator, executor, or client tool such as a code generator.
20182018

20192019
:: A _built-in directive_ is any directive defined within this specification.
20202020

2021-
GraphQL implementations should provide the `@skip` and `@include` directives.
2021+
GraphQL implementations should provide the `@skip`, `@include` and
2022+
`@nullOnError` directives.
20222023

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

0 commit comments

Comments
 (0)