Skip to content

Commit 1a1c3a9

Browse files
committed
Call rescue_from when skipping items
1 parent 0b2f45a commit 1a1c3a9

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

lib/graphql/execution.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,12 @@ class Skip < GraphQL::Error; end
1414
# Just a singleton for implementing {Query::Context#skip}
1515
# @api private
1616
SKIP = Skip.new
17+
18+
# @api private
19+
class SkipFromParentList < GraphQL::Error; end
20+
21+
# Just a singleton for implementing {Query::Context#skip}
22+
# @api private
23+
SKIP_FROM_PARENT_LIST = SkipFromParentList.new
1724
end
1825
end

lib/graphql/execution/interpreter/runtime.rb

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -523,14 +523,17 @@ def evaluate_selection_with_args(arguments, field_defn, next_path, ast_node, fie
523523
rescue GraphQL::ExecutionError => err
524524
err
525525
rescue StandardError => err
526-
if selection_result.has_graphql_graph_parent_that_skips_list_items_that_raise
527-
nil
528-
else
529-
begin
526+
begin
527+
if selection_result.has_graphql_graph_parent_that_skips_list_items_that_raise
528+
set_interpreter_context(:current_list_item_to_skip, nil) # Just set the key for now
529+
result = query.handle_or_reraise(err)
530+
delete_interpreter_context(:current_list_item_to_skip)
531+
result
532+
else
530533
query.handle_or_reraise(err)
531-
rescue GraphQL::ExecutionError => ex_err
532-
ex_err
533534
end
535+
rescue GraphQL::ExecutionError => ex_err
536+
ex_err
534537
end
535538
end
536539
after_lazy(app_result, owner: owner_type, field: field_defn, path: next_path, ast_node: ast_node, owner_object: object, arguments: resolved_arguments, result_name: result_name, result: selection_result) do |inner_result|
@@ -560,7 +563,7 @@ def dead_result?(selection_result)
560563

561564
def set_result(selection_result, result_name, value)
562565
if !dead_result?(selection_result)
563-
if value == GraphQL::Execution::SKIP
566+
if value == GraphQL::Execution::SKIP_FROM_PARENT_LIST
564567
if selection_result.graphql_skip_list_items_that_raise
565568
case selection_result
566569
when GraphQLResultHash then selection_result.delete(result_name) # TODO: unify `#delete` interface with `#graphql_skip_at`
@@ -575,7 +578,7 @@ def set_result(selection_result, result_name, value)
575578
if parent.nil? # This is a top-level result hash
576579
@response = nil
577580
else
578-
set_result(parent, name_in_parent, GraphQL::Execution::SKIP)
581+
set_result(parent, name_in_parent, GraphQL::Execution::SKIP_FROM_PARENT_LIST)
579582
set_graphql_dead(selection_result)
580583
end
581584
end
@@ -626,11 +629,7 @@ def set_graphql_dead(selection_result)
626629
def continue_value(path, value, parent_type, field, is_non_null, ast_node, result_name, selection_result) # rubocop:disable Metrics/ParameterLists
627630
case value
628631
when nil
629-
if selection_result.has_graphql_graph_parent_that_skips_list_items_that_raise
630-
# This writes the `nil` in, we need to patch it to skip instead.
631-
print("skip!")
632-
set_result(selection_result, result_name, GraphQL::Execution::SKIP)
633-
elsif is_non_null
632+
if is_non_null
634633
set_result(selection_result, result_name, nil) do
635634
# This block is called if `result_name` is not dead. (Maybe a previous invalid nil caused it be marked dead.)
636635
err = parent_type::InvalidNullError.new(parent_type, field, value)
@@ -686,6 +685,14 @@ def continue_value(path, value, parent_type, field, is_non_null, ast_node, resul
686685
raise "Invariant: unexpected result class #{selection_result.class} (#{selection_result.inspect})"
687686
end
688687
HALT
688+
elsif GraphQL::Execution::SKIP_FROM_PARENT_LIST == value
689+
if selection_result.has_graphql_graph_parent_that_skips_list_items_that_raise
690+
# This writes the `nil` in, we need to patch it to skip instead.
691+
puts("skip!")
692+
set_result(selection_result, result_name, GraphQL::Execution::SKIP_FROM_PARENT_LIST)
693+
else
694+
raise "Cannot skip list items from lists not marked `skip_items_on_raise: true`"
695+
end
689696
else
690697
# What could this actually _be_? Anyhow,
691698
# preserve the default behavior of doing nothing with it.

lib/graphql/query/context.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ def skip
1111
GraphQL::Execution::SKIP
1212
end
1313

14+
# Return this value to tell the runtime
15+
# to exclude this whole object from parent list.
16+
#
17+
# The runtime will find the find the nearest parent list marked `skip_items_on_raise: true`,
18+
# and exclude the entire list item (including this object).
19+
def skip_from_parent_list
20+
GraphQL::Execution::SKIP_FROM_PARENT_LIST
21+
end
22+
1423
# Add error at query-level.
1524
# @param error [GraphQL::ExecutionError] an execution error
1625
# @return [void]

0 commit comments

Comments
 (0)