Skip to content

Commit 42d5736

Browse files
committed
Move argumenterror handling to method rescues to reduce nesting of happy path
1 parent ecfd85c commit 42d5736

File tree

1 file changed

+55
-53
lines changed

1 file changed

+55
-53
lines changed

lib/graphql/schema/field.rb

Lines changed: 55 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -600,70 +600,66 @@ def authorized?(object, args, context)
600600
def resolve(object, args, query_ctx)
601601
# Unwrap the GraphQL object to get the application object.
602602
application_object = object.object
603+
method_receiver = nil
604+
method_to_call = nil
605+
method_args = nil
603606

604607
Schema::Validator.validate!(validators, application_object, query_ctx, args)
605608

606609
query_ctx.schema.after_lazy(self.authorized?(application_object, args, query_ctx)) do |is_authorized|
607610
if is_authorized
608611
with_extensions(object, args, query_ctx) do |obj, ruby_kwargs|
609-
begin
610-
method_receiver = nil
611-
method_to_call = nil
612-
if @resolver_class
613-
if obj.is_a?(GraphQL::Schema::Object)
614-
obj = obj.object
615-
end
616-
obj = @resolver_class.new(object: obj, context: query_ctx, field: self)
612+
method_args = ruby_kwargs
613+
if @resolver_class
614+
if obj.is_a?(GraphQL::Schema::Object)
615+
obj = obj.object
617616
end
617+
obj = @resolver_class.new(object: obj, context: query_ctx, field: self)
618+
end
618619

619-
# Find a way to resolve this field, checking:
620-
#
621-
# - A method on the type instance;
622-
# - Hash keys, if the wrapped object is a hash;
623-
# - A method on the wrapped object;
624-
# - Or, raise not implemented.
625-
#
626-
if obj.respond_to?(resolver_method)
627-
method_to_call = resolver_method
628-
method_receiver = obj
629-
# Call the method with kwargs, if there are any
630-
if ruby_kwargs.any?
631-
obj.public_send(resolver_method, **ruby_kwargs)
632-
else
633-
obj.public_send(resolver_method)
634-
end
635-
elsif obj.object.is_a?(Hash)
636-
inner_object = obj.object
637-
if @dig_keys
638-
inner_object.dig(*@dig_keys)
639-
elsif inner_object.key?(@method_sym)
640-
inner_object[@method_sym]
641-
else
642-
inner_object[@method_str]
643-
end
644-
elsif obj.object.respond_to?(@method_sym)
645-
method_to_call = @method_sym
646-
method_receiver = obj.object
647-
if ruby_kwargs.any?
648-
obj.object.public_send(@method_sym, **ruby_kwargs)
649-
else
650-
obj.object.public_send(@method_sym)
651-
end
620+
# Find a way to resolve this field, checking:
621+
#
622+
# - A method on the type instance;
623+
# - Hash keys, if the wrapped object is a hash;
624+
# - A method on the wrapped object;
625+
# - Or, raise not implemented.
626+
#
627+
if obj.respond_to?(resolver_method)
628+
method_to_call = resolver_method
629+
method_receiver = obj
630+
# Call the method with kwargs, if there are any
631+
if ruby_kwargs.any?
632+
obj.public_send(resolver_method, **ruby_kwargs)
633+
else
634+
obj.public_send(resolver_method)
635+
end
636+
elsif obj.object.is_a?(Hash)
637+
inner_object = obj.object
638+
if @dig_keys
639+
inner_object.dig(*@dig_keys)
640+
elsif inner_object.key?(@method_sym)
641+
inner_object[@method_sym]
652642
else
653-
raise <<-ERR
654-
Failed to implement #{@owner.graphql_name}.#{@name}, tried:
643+
inner_object[@method_str]
644+
end
645+
elsif obj.object.respond_to?(@method_sym)
646+
method_to_call = @method_sym
647+
method_receiver = obj.object
648+
if ruby_kwargs.any?
649+
obj.object.public_send(@method_sym, **ruby_kwargs)
650+
else
651+
obj.object.public_send(@method_sym)
652+
end
653+
else
654+
raise <<-ERR
655+
Failed to implement #{@owner.graphql_name}.#{@name}, tried:
655656
656-
- `#{obj.class}##{resolver_method}`, which did not exist
657-
- `#{obj.object.class}##{@method_sym}`, which did not exist
658-
- Looking up hash key `#{@method_sym.inspect}` or `#{@method_str.inspect}` on `#{obj.object}`, but it wasn't a Hash
657+
- `#{obj.class}##{resolver_method}`, which did not exist
658+
- `#{obj.object.class}##{@method_sym}`, which did not exist
659+
- Looking up hash key `#{@method_sym.inspect}` or `#{@method_str.inspect}` on `#{obj.object}`, but it wasn't a Hash
659660
660-
To implement this field, define one of the methods above (and check for typos)
661-
ERR
662-
end
663-
rescue ArgumentError
664-
assert_satisfactory_implementation(method_receiver, method_to_call, ruby_kwargs)
665-
# if the line above doesn't raise, re-raise
666-
raise
661+
To implement this field, define one of the methods above (and check for typos)
662+
ERR
667663
end
668664
end
669665
else
@@ -683,6 +679,12 @@ def resolve(object, args, query_ctx)
683679
rescue GraphQL::ExecutionError => err
684680
err
685681
end
682+
rescue ArgumentError
683+
if method_receiver && method_to_call
684+
assert_satisfactory_implementation(method_receiver, method_to_call, method_args)
685+
end
686+
# if the line above doesn't raise, re-raise
687+
raise
686688
end
687689

688690
# @param ctx [GraphQL::Query::Context]

0 commit comments

Comments
 (0)