@@ -48,59 +48,85 @@ def append_selection(ast_node)
4848 nil
4949 end
5050
51- def coerce_arguments ( argument_owner , ast_arguments_or_hash )
51+ def coerce_arguments ( argument_owner , ast_arguments_or_hash , run_loads = true )
5252 arg_defns = argument_owner . arguments ( @selections_step . query . context )
5353 if arg_defns . empty?
5454 return EmptyObjects ::EMPTY_HASH
5555 end
5656 args_hash = { }
57- if ast_arguments_or_hash . is_a? ( Hash )
58- ast_arguments_or_hash . each do |key , value |
59- key_s = nil
60- arg_defn = arg_defns . each_value . find { |a |
61- a . keyword == key || a . graphql_name == ( key_s ||= String ( key ) )
62- }
63- coerce_argument_value ( args_hash , arg_defn , value )
64- end
65- else
66- ast_arguments_or_hash . each { |arg_node |
67- arg_defn = arg_defns [ arg_node . name ]
68- coerce_argument_value ( args_hash , arg_defn , arg_node . value )
69- }
57+ if ast_arguments_or_hash . nil? # This can happen with `.trigger`
58+ return args_hash
7059 end
71- # TODO refactor the loop above into this one
60+
61+ arg_inputs_are_h = ast_arguments_or_hash . is_a? ( Hash )
62+
7263 arg_defns . each do |arg_graphql_name , arg_defn |
73- if arg_defn . default_value? && !args_hash . key? ( arg_defn . keyword )
74- coerce_argument_value ( args_hash , arg_defn , arg_defn . default_value )
64+ arg_value = nil
65+ was_found = false
66+ if arg_inputs_are_h
67+ ast_arguments_or_hash . each do |key , value |
68+ if key == arg_defn . keyword || key . to_s == arg_defn . graphql_name
69+ arg_value = value
70+ was_found = true
71+ break
72+ end
73+ end
74+ else
75+ ast_arguments_or_hash . each do |arg_node |
76+ if arg_node . name == arg_defn . graphql_name
77+ arg_value = arg_node . value
78+ was_found = true
79+ break
80+ end
81+ end
82+ end
83+
84+ if arg_value . is_a? ( Language ::Nodes ::VariableIdentifier )
85+ vars = @selections_step . query . variables
86+ arg_value = if vars . key? ( arg_value . name )
87+ vars [ arg_value . name ]
88+ elsif vars . key? ( arg_value . name . to_sym )
89+ vars [ arg_value . name . to_sym ]
90+ else
91+ was_found = false
92+ nil
93+ end
94+ end
95+
96+ if !was_found && arg_defn . default_value?
97+ was_found = true
98+ arg_value = arg_defn . default_value
99+ end
100+
101+ if was_found
102+ coerce_argument_value ( args_hash , arg_defn , arg_value , run_loads )
75103 end
76104 end
77105
78106 args_hash
79107 end
80108
81- def coerce_argument_value ( arguments , arg_defn , arg_value , target_keyword : arg_defn . keyword , as_type : nil )
109+ def coerce_argument_value ( arguments , arg_defn , arg_value , run_loads , target_keyword : run_loads ? arg_defn . keyword : arg_defn . graphql_name , as_type : nil )
82110 arg_t = as_type || arg_defn . type
83111 if arg_t . non_null?
84112 arg_t = arg_t . of_type
85113 end
86114
87- arg_value = if arg_value . is_a? ( Language ::Nodes ::VariableIdentifier )
115+ if arg_value . is_a? ( Language ::Nodes ::VariableIdentifier )
88116 vars = @selections_step . query . variables
89- if vars . key? ( arg_value . name )
117+ arg_value = if vars . key? ( arg_value . name )
90118 vars [ arg_value . name ]
91119 elsif vars . key? ( arg_value . name . to_sym )
92120 vars [ arg_value . name . to_sym ]
93121 else
94- return # not present
122+ nil
95123 end
96- elsif arg_value . is_a? ( Language ::Nodes ::NullValue )
97- nil
124+ end
125+
126+ if arg_value . is_a? ( Language ::Nodes ::NullValue )
127+ arg_value = nil
98128 elsif arg_value . is_a? ( Language ::Nodes ::Enum )
99- arg_value . name
100- elsif arg_value . is_a? ( Language ::Nodes ::InputObject )
101- arg_value . arguments # rubocop:disable Development/ContextIsPassedCop
102- else
103- arg_value
129+ arg_value = arg_value . name
104130 end
105131
106132 ctx = @selections_step . query . context
@@ -111,7 +137,7 @@ def coerce_argument_value(arguments, arg_defn, arg_value, target_keyword: arg_de
111137 arg_value = Array ( arg_value )
112138 inner_t = arg_t . of_type
113139 result = Array . new ( arg_value . size )
114- arg_value . each_with_index { |v , i | coerce_argument_value ( result , arg_defn , v , target_keyword : i , as_type : inner_t ) }
140+ arg_value . each_with_index { |v , i | coerce_argument_value ( result , arg_defn , v , run_loads , target_keyword : i , as_type : inner_t ) }
115141 result
116142 end
117143 elsif arg_t . kind . leaf?
@@ -125,7 +151,8 @@ def coerce_argument_value(arguments, arg_defn, arg_value, target_keyword: arg_de
125151 end
126152 end
127153 elsif arg_t . kind . input_object?
128- input_obj_args = coerce_arguments ( arg_t , arg_value )
154+ input_obj_vals = arg_value . is_a? ( Language ::Nodes ::InputObject ) ? arg_value . arguments : arg_value # rubocop:disable Development/ContextIsPassedCop
155+ input_obj_args = coerce_arguments ( arg_t , input_obj_vals )
129156 arg_t . new ( nil , ruby_kwargs : input_obj_args , context : @selections_step . query . context , defaults_used : nil )
130157 else
131158 raise "Unsupported argument value: #{ arg_t . to_type_signature } / #{ arg_value . class } (#{ arg_value . inspect } )"
@@ -145,7 +172,7 @@ def coerce_argument_value(arguments, arg_defn, arg_value, target_keyword: arg_de
145172
146173 if arg_value . is_a? ( GraphQL ::Error )
147174 @arguments = arg_value
148- elsif arg_defn . loads && as_type . nil? && !arg_value . nil?
175+ elsif run_loads && arg_defn . loads && as_type . nil? && !arg_value . nil?
149176 # This is for legacy compat:
150177 load_receiver = if ( r = @field_definition . resolver )
151178 r . new ( field : @field_definition , context : @selections_step . query . context , object : nil )
@@ -263,7 +290,8 @@ def build_arguments
263290 arguments = coerce_arguments ( @field_definition , @ast_node . arguments ) # rubocop:disable Development/ContextIsPassedCop
264291 @arguments ||= arguments # may have already been set to an error
265292
266- if @pending_steps . nil? || @pending_steps . size == 0
293+ if ( @pending_steps . nil? || @pending_steps . size == 0 ) &&
294+ @field_results . nil? # Make sure the arguments flow didn't already call through
267295 execute_field
268296 end
269297 end
@@ -323,6 +351,14 @@ def execute_field
323351 is_authed = @field_definition . authorized? ( o , @arguments , ctx )
324352 if is_authed
325353 authorized_objects << o
354+ else
355+ begin
356+ err = GraphQL ::UnauthorizedFieldError . new ( object : o , type : @parent_type , context : ctx , field : @field_definition )
357+ authorized_objects << query . schema . unauthorized_object ( err )
358+ is_authed = true
359+ rescue GraphQL ::ExecutionError => exec_err
360+ add_graphql_error ( exec_err )
361+ end
326362 end
327363 is_authed
328364 }
@@ -616,29 +652,35 @@ def resolve_batch(objects, context, args_hash)
616652 method_receiver = @field_definition . dynamic_introspection ? @field_definition . owner : @parent_type
617653 case @field_definition . execution_next_mode
618654 when :resolve_batch
619- if args_hash . empty?
620- method_receiver . public_send ( @field_definition . execution_next_mode_key , objects , context )
621- else
655+ begin
622656 method_receiver . public_send ( @field_definition . execution_next_mode_key , objects , context , **args_hash )
657+ rescue GraphQL ::ExecutionError => exec_err
658+ Array . new ( objects . size , exec_err )
623659 end
624660 when :resolve_static
625- result = if args_hash . empty?
626- method_receiver . public_send ( @field_definition . execution_next_mode_key , context )
627- else
628- method_receiver . public_send ( @field_definition . execution_next_mode_key , context , **args_hash )
629- end
661+ result = method_receiver . public_send ( @field_definition . execution_next_mode_key , context , **args_hash )
630662 Array . new ( objects . size , result )
631663 when :resolve_each
632- if args_hash . empty?
633- objects . map { | o | method_receiver . public_send ( @field_definition . execution_next_mode_key , o , context ) }
634- else
635- objects . map { | o | method_receiver . public_send ( @field_definition . execution_next_mode_key , o , context , ** args_hash ) }
664+ objects . map do | o |
665+ method_receiver . public_send ( @field_definition . execution_next_mode_key , o , context , ** args_hash )
666+ rescue GraphQL :: ExecutionError => err
667+ err
636668 end
637669 when :hash_key
638670 objects . map { |o | o [ @field_definition . execution_next_mode_key ] }
639671 when :direct_send
640672 if args_hash . empty?
641- objects . map { |o | o . public_send ( @field_definition . execution_next_mode_key ) }
673+ objects . map do |o |
674+ o . public_send ( @field_definition . execution_next_mode_key )
675+ rescue GraphQL ::ExecutionError => err
676+ err
677+ rescue StandardError => stderr
678+ begin
679+ @selections_step . query . handle_or_reraise ( stderr )
680+ rescue GraphQL ::ExecutionError => ex_err
681+ ex_err
682+ end
683+ end
642684 else
643685 objects . map { |o | o . public_send ( @field_definition . execution_next_mode_key , **args_hash ) }
644686 end
@@ -684,17 +726,12 @@ def resolve_batch(objects, context, args_hash)
684726 if @field_definition . dynamic_introspection
685727 obj_inst = @owner . wrap ( obj_inst , context )
686728 end
687- if args_hash . empty?
688- obj_inst . public_send ( @field_definition . execution_next_mode_key )
689- else
690- obj_inst . public_send ( @field_definition . execution_next_mode_key , **args_hash )
691- end
729+ obj_inst . public_send ( @field_definition . execution_next_mode_key , **args_hash )
692730 end
693731 else
694732 raise "Batching execution for #{ path } not implemented (execution_next_mode: #{ @execution_next_mode . inspect } ); provide `resolve_static:`, `resolve_batch:`, `hash_key:`, `method:`, or use a compatibility plug-in"
695733 end
696734 end
697-
698735 end
699736
700737 class RawValueFieldResolveStep < FieldResolveStep
0 commit comments