@@ -460,11 +460,35 @@ yielded a value may be cancelled to avoid unnecessary work.
460460
461461Additionally, the path of each {asyncRecord} in {subsequentPayloads} must be
462462compared with the path of the field that ultimately resolved to {null}. If the
463- path of any {asyncRecord} starts with, but is not equal to, the path of the
464- resolved {null}, the {asyncRecord} must be removed from {subsequentPayloads} and
465- its result must not be sent to clients. If these async records have not yet
466- executed or have not yet yielded a value they may also be cancelled to avoid
467- unnecessary work.
463+ path of any {asyncRecord} starts with the path of the resolved {null}, the
464+ {asyncRecord} must be removed from {subsequentPayloads} and its result must not
465+ be sent to clients. If these async records have not yet executed or have not yet
466+ yielded a value they may also be cancelled to avoid unnecessary work.
467+
468+ For example, assume the field ` alwaysThrows ` is a ` Non-Null ` type that always
469+ raises a field error:
470+
471+ ``` graphql example
472+ {
473+ myObject {
474+ ... @defer {
475+ name
476+ }
477+ alwaysThrows
478+ }
479+ }
480+ ```
481+
482+ In this case, only one response should be sent. The async payload record
483+ associated with the ` @defer ` directive should be removed and it's execution may
484+ be cancelled.
485+
486+ ``` json example
487+ {
488+ "data" : { "myObject" : null },
489+ "hasNext" : false
490+ }
491+ ```
468492
469493Note: See [ Handling Field Errors] ( #sec-Handling-Field-Errors ) for more about
470494this behavior.
@@ -756,7 +780,7 @@ variableValues, parentRecord, subsequentPayloads):
756780 - If {errors} is not empty:
757781 - Add an entry to {payload} named ` errors ` with the value {errors}.
758782 - If a field error was raised, causing a {null} to be propagated to
759- {responseValue}, and {objectType} is a Non-Nullable type :
783+ {responseValue}:
760784 - Add an entry to {payload} named ` data ` with the value {null}.
761785 - Otherwise:
762786 - Add an entry to {payload} named ` data ` with the value {resultMap}.
@@ -1120,16 +1144,121 @@ When a field error is raised inside `ExecuteDeferredFragment` or
11201144That is, the null resulting from a ` Non-Null ` type cannot propagate outside of
11211145the boundary of the defer or stream payload.
11221146
1123- If a fragment with the ` defer ` directive is spread on a Non-Nullable object
1124- type, and a field error has caused a {null} to propagate to the associated
1125- object, the {null} should not propagate any further, and the associated Defer
1126- Payload's ` data ` field must be set to {null}.
1147+ If a field error is raised while executing the selection set of a fragment with
1148+ the ` defer ` directive, causing a {null} to propagate to the object containing
1149+ this fragment, the {null} should not propagate any further. In this case, the
1150+ associated Defer Payload's ` data ` field must be set to {null}.
1151+
1152+ For example, assume the ` month ` field is a ` Non-Null ` type that raises a field
1153+ error:
1154+
1155+ ``` graphql example
1156+ {
1157+ birthday {
1158+ ... @defer {
1159+ month
1160+ }
1161+ }
1162+ }
1163+ ```
1164+
1165+ Response 1, the initial response is sent:
1166+
1167+ ``` json example
1168+ {
1169+ "data" : { "birthday" : {} },
1170+ "hasNext" : true
1171+ }
1172+ ```
1173+
1174+ Response 2, the defer payload is sent. The {data} entry has been set to {null},
1175+ as this {null} as propagated as high as the error boundary will allow.
1176+
1177+ ``` json example
1178+ {
1179+ "incremental" : [
1180+ {
1181+ "path" : [" birthday" ],
1182+ "data" : null
1183+ }
1184+ ],
1185+ "hasNext" : false
1186+ }
1187+ ```
11271188
11281189If the ` stream ` directive is present on a list field with a Non-Nullable inner
11291190type, and a field error has caused a {null} to propagate to the list item, the
11301191{null} should not propagate any further, and the associated Stream Payload's
11311192` item ` field must be set to {null}.
11321193
1194+ For example, assume the ` films ` field is a ` List ` type with an ` Non-Null ` inner
1195+ type. In this case, the second list item raises a field error:
1196+
1197+ ``` graphql example
1198+ {
1199+ films @stream (initialCount : 1 )
1200+ }
1201+ ```
1202+
1203+ Response 1, the initial response is sent:
1204+
1205+ ``` json example
1206+ {
1207+ "data" : { "films" : [" A New Hope" ] },
1208+ "hasNext" : true
1209+ }
1210+ ```
1211+
1212+ Response 2, the first stream payload is sent. The {items} entry has been set to
1213+ {null}, as this {null} as propagated as high as the error boundary will allow.
1214+
1215+ ``` json example
1216+ {
1217+ "incremental" : [
1218+ {
1219+ "path" : [" films" , 1 ],
1220+ "items" : null
1221+ }
1222+ ],
1223+ "hasNext" : false
1224+ }
1225+ ```
1226+
1227+ In this alternative example, assume the ` films ` field is a ` List ` type without a
1228+ ` Non-Null ` inner type. In this case, the second list item also raises a field
1229+ error:
1230+
1231+ ``` graphql example
1232+ {
1233+ films @stream (initialCount : 1 )
1234+ }
1235+ ```
1236+
1237+ Response 1, the initial response is sent:
1238+
1239+ ``` json example
1240+ {
1241+ "data" : { "films" : [" A New Hope" ] },
1242+ "hasNext" : true
1243+ }
1244+ ```
1245+
1246+ Response 2, the first stream payload is sent. The {items} entry has been set to
1247+ a list containing {null}, as this {null} has only propagated as high as the list
1248+ item.
1249+
1250+ ``` json example
1251+ {
1252+ "incremental" : [
1253+ {
1254+ "path" : [" films" , 1 ],
1255+ "items" : [null ]
1256+ }
1257+ ],
1258+ "hasNext" : false
1259+ }
1260+ ```
1261+
11331262If all fields from the root of the request to the source of the field error
11341263return ` Non-Null ` types, then the {"data"} entry in the response should be
11351264{null}.
0 commit comments