@@ -321,8 +321,20 @@ def evaluate_selection_with_args(kwarg_arguments, field_defn, next_path, ast_nod
321
321
end
322
322
end
323
323
324
+ def dead_result? ( selection_result )
325
+ r = selection_result
326
+ while r
327
+ if r . graphql_dead
328
+ return true
329
+ else
330
+ r = r . graphql_parent
331
+ end
332
+ end
333
+ false
334
+ end
335
+
324
336
def set_result ( selection_result , result_name , value )
325
- if !selection_result . graphql_dead
337
+ if !dead_result? ( selection_result )
326
338
if value . nil? &&
327
339
( nn = selection_result . graphql_non_null ) &&
328
340
( nn == true || nn . include? ( result_name ) )
@@ -333,6 +345,9 @@ def set_result(selection_result, result_name, value)
333
345
@response = nil
334
346
else
335
347
set_result ( parent , name_in_parent , nil )
348
+ # This is odd, but it's how it used to work. Even if `parent` _would_ accept
349
+ # a `nil`, it's marked dead. TODO: check the spec, is there a reason for this?
350
+ parent . graphql_dead = true
336
351
end
337
352
else
338
353
selection_result [ result_name ] = value
@@ -346,7 +361,7 @@ def continue_value(path, value, parent_type, field, is_non_null, ast_node, resul
346
361
when nil
347
362
if is_non_null
348
363
err = parent_type ::InvalidNullError . new ( parent_type , field , value )
349
- if !selection_result . graphql_dead
364
+ if !dead_result? ( selection_result )
350
365
schema . type_error ( err , context )
351
366
set_result ( selection_result , result_name , nil )
352
367
selection_result . graphql_dead = true
@@ -360,11 +375,12 @@ def continue_value(path, value, parent_type, field, is_non_null, ast_node, resul
360
375
# to avoid the overhead of checking three different classes
361
376
# every time.
362
377
if value . is_a? ( GraphQL ::ExecutionError )
363
- if !selection_result . graphql_dead
378
+ if !dead_result? ( selection_result )
364
379
value . path ||= path
365
380
value . ast_node ||= ast_node
366
381
context . errors << value
367
382
set_result ( selection_result , result_name , nil )
383
+ selection_result . graphql_dead = true
368
384
end
369
385
HALT
370
386
elsif value . is_a? ( GraphQL ::UnauthorizedError )
@@ -376,7 +392,6 @@ def continue_value(path, value, parent_type, field, is_non_null, ast_node, resul
376
392
err
377
393
end
378
394
continue_value ( path , next_value , parent_type , field , is_non_null , ast_node , result_name , selection_result )
379
- HALT
380
395
elsif GraphQL ::Execution ::Execute ::SKIP == value
381
396
HALT
382
397
else
@@ -387,7 +402,7 @@ def continue_value(path, value, parent_type, field, is_non_null, ast_node, resul
387
402
when Array
388
403
# It's an array full of execution errors; add them all.
389
404
if value . any? && value . all? { |v | v . is_a? ( GraphQL ::ExecutionError ) }
390
- if !selection_result . graphql_dead
405
+ if !dead_result? ( selection_result )
391
406
value . each_with_index do |error , index |
392
407
error . ast_node ||= ast_node
393
408
error . path ||= path + ( field . type . list? ? [ index ] : [ ] )
0 commit comments