Skip to content

Commit

Permalink
Merge pull request #4079 from rmosolgo/fix-prepare-error-complexity
Browse files Browse the repository at this point in the history
Handle raised ExecutionErrors from prepare when calculating complexity
  • Loading branch information
rmosolgo committed May 27, 2022
2 parents 01cb5b4 + 811218b commit 9411e98
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
8 changes: 7 additions & 1 deletion lib/graphql/schema/field.rb
Expand Up @@ -496,7 +496,13 @@ def calculate_complexity(query:, nodes:, child_complexity:)
case defined_complexity
when Proc
arguments = query.arguments_for(nodes.first, self)
defined_complexity.call(query.context, arguments.keyword_arguments, child_complexity)
if arguments.is_a?(GraphQL::ExecutionError)
return child_complexity
elsif arguments.respond_to?(:keyword_arguments)
arguments = arguments.keyword_arguments
end

defined_complexity.call(query.context, arguments, child_complexity)
when Numeric
defined_complexity + child_complexity
else
Expand Down
29 changes: 26 additions & 3 deletions spec/graphql/analysis/ast/query_complexity_spec.rb
Expand Up @@ -8,7 +8,8 @@
GraphQL::Analysis::AST.analyze_multiplex(multiplex, [GraphQL::Analysis::AST::QueryComplexity])
}
let(:variables) { {} }
let(:query) { GraphQL::Query.new(schema, query_string, variables: variables) }
let(:query_context) { {} }
let(:query) { GraphQL::Query.new(schema, query_string, context: query_context, variables: variables) }
let(:multiplex) {
GraphQL::Execution::Multiplex.new(
schema: schema,
Expand Down Expand Up @@ -377,10 +378,20 @@ class DoubleComplexity < GraphQL::Schema::Object

class Query < GraphQL::Schema::Object
field :complexity, SingleComplexity do
argument :int_value, Int, required: false
argument :int_value, Int, required: false, prepare: ->(val, ctx) {
if ctx[:raise_prepare_error]
raise GraphQL::ExecutionError, "Boom"
else
val
end
}
complexity ->(ctx, args, child_complexity) { args[:int_value] + child_complexity }
end

def complexity(int_value:)
{ value: int_value }
end

field :inner_complexity, ComplexityInterface do
argument :value, Int, required: false
end
Expand All @@ -390,7 +401,7 @@ class Query < GraphQL::Schema::Object
orphan_types(DoubleComplexity)
end

let(:query) { GraphQL::Query.new(complexity_schema, query_string) }
let(:query) { GraphQL::Query.new(complexity_schema, query_string, context: query_context) }
let(:complexity_schema) { CustomComplexitySchema }
let(:query_string) {%|
{
Expand Down Expand Up @@ -426,6 +437,18 @@ class Query < GraphQL::Schema::Object
assert_equal 5, complexity
end
end

describe "when prepare raises an error" do
let(:query_string) { "{ complexity(intValue: 3) { value } }"}
let(:query_context) { { raise_prepare_error: true } }

it "handles it nicely" do
result = query.result
assert_equal ["Boom"], result["errors"].map { |e| e["message"] }
complexity = reduce_result.first
assert_equal 0.1, complexity
end
end
end

describe "custom complexities by complexity_for(...)" do
Expand Down

0 comments on commit 9411e98

Please sign in to comment.