Skip to content

Commit e2eff74

Browse files
committed
Migrate to RuntimeError for error checks, add Finalizers API
1 parent 3584553 commit e2eff74

7 files changed

Lines changed: 32 additions & 14 deletions

File tree

lib/graphql.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ def self.eager_load!
2121
class Error < StandardError
2222
end
2323

24-
class RuntimeError < Error
25-
end
26-
2724
# This error is raised when GraphQL-Ruby encounters a situation
2825
# that it *thought* would never happen. Please report this bug!
2926
class InvariantError < Error
@@ -122,6 +119,7 @@ class << self
122119
autoload :ParseError, "graphql/parse_error"
123120
autoload :Backtrace, "graphql/backtrace"
124121

122+
autoload :RuntimeError, "graphql/runtime_error"
125123
autoload :UnauthorizedError, "graphql/unauthorized_error"
126124
autoload :UnauthorizedEnumValueError, "graphql/unauthorized_enum_value_error"
127125
autoload :UnauthorizedFieldError, "graphql/unauthorized_field_error"

lib/graphql/execution/next.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ def self.run_all(schema, query_options, context: {}, max_complexity: schema.max_
6767
runner = Runner.new(multiplex, **schema.execution_next_options)
6868
runner.execute
6969
end
70+
71+
module Finalizer
72+
attr_accessor :path
73+
def assign_graphql_result(query, result_data, result_key)
74+
raise RequiredImplementationMissingError
75+
end
76+
end
7077
end
7178
end
7279
end

lib/graphql/execution/next/field_resolve_step.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def coerce_argument_value(arguments, arg_defn, arg_value, run_loads, target_keyw
171171
end
172172
end
173173

174-
if arg_value.is_a?(GraphQL::Error)
174+
if arg_value.is_a?(GraphQL::RuntimeError)
175175
@arguments = arg_value
176176
elsif run_loads && arg_defn.loads && as_type.nil? && !arg_value.nil?
177177
# This is for legacy compat:
@@ -292,7 +292,7 @@ def build_arguments
292292
def execute_field
293293
objects = @selections_step.objects
294294
# TODO not as good because only one error?
295-
if @arguments.is_a?(GraphQL::Error)
295+
if @arguments.is_a?(GraphQL::RuntimeError)
296296
@field_results = Array.new(objects.size, @arguments)
297297
@object_is_authorized = AlwaysAuthorized
298298
build_results
@@ -520,7 +520,7 @@ def build_results
520520
else
521521
nil
522522
end
523-
elsif field_result.is_a?(GraphQL::Error)
523+
elsif field_result.is_a?(GraphQL::RuntimeError)
524524
add_graphql_error(field_result)
525525
else
526526
# TODO `nil`s in [T!] types aren't handled
@@ -596,7 +596,7 @@ def build_graphql_result(graphql_result, key, field_result, return_type, is_nn,
596596
else
597597
graphql_result[key] = nil
598598
end
599-
elsif field_result.is_a?(GraphQL::Error)
599+
elsif field_result.is_a?(GraphQL::RuntimeError)
600600
graphql_result[key] = add_graphql_error(field_result)
601601
elsif is_list
602602
if is_nn

lib/graphql/execution/next/load_argument_step.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def call
4545
private
4646

4747
def assign_value
48-
if @loaded_value.is_a?(GraphQL::Error)
48+
if @loaded_value.is_a?(GraphQL::RuntimeError)
4949
@loaded_value.path = @field_resolve_step.path
5050
@field_resolve_step.arguments = @loaded_value
5151
else

lib/graphql/execution/next/prepare_object_step.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def create_result
103103
else
104104
@graphql_result[@key] = @field_resolve_step.add_graphql_error(@authorization_error)
105105
end
106-
rescue GraphQL::Error => err
106+
rescue GraphQL::RuntimeError => err
107107
if @is_non_null
108108
@graphql_result[@key] = @field_resolve_step.add_non_null_error(@is_from_array)
109109
else

lib/graphql/execution/next/runner.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def execute
184184
result
185185
else
186186
data = result["data"]
187-
data = propagate_errors(data, query)
187+
data = run_finalizers(data, query)
188188
errors = []
189189
query.context.errors.each do |err|
190190
if err.respond_to?(:to_h)
@@ -252,8 +252,8 @@ def lazy?(object)
252252

253253
private
254254

255-
def propagate_errors(data, query)
256-
paths_to_check = query.context.errors.map(&:path)
255+
def run_finalizers(data, query)
256+
paths_to_check = query.finalizers.map(&:path)
257257
paths_to_check.compact! # root-level auth errors currently come without a path
258258
# TODO dry with above?
259259
# This is also where a query-level "Step" would be used?
@@ -287,7 +287,7 @@ def check_object_result(query, result_h, static_type, ast_selections, current_ex
287287
result_type = result_type.of_type
288288
end
289289

290-
new_result_value = if result_value.is_a?(GraphQL::Error)
290+
new_result_value = if result_value.is_a?(Finalizer)
291291
result_value.path = current_result_path.dup
292292
result_value.assign_graphql_result(query, result_h, key)
293293
result_h.key?(key) ? result_h[key] : :unassigned
@@ -340,7 +340,7 @@ def check_list_result(query, result_arr, inner_type, ast_selections, current_exe
340340
new_invalid_null = false
341341
result_arr.each_with_index do |result_item, idx|
342342
current_result_path << idx
343-
new_result = if result_item.is_a?(GraphQL::Error)
343+
new_result = if result_item.is_a?(Finalizer)
344344
result_item.path = current_result_path.dup
345345
result_item.assign_graphql_result(query, result_arr, idx)
346346
result_arr[idx]

lib/graphql/query.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,19 @@ def selected_operation
298298
with_prepared_ast { @selected_operation }
299299
end
300300

301+
# @return [Array<Execution::Next::Finalizer>]
302+
def finalizers
303+
@finalizers ? (@finalizers + context.errors) : context.errors
304+
end
305+
306+
# @param finalizer [Execution::Next::Finalizer]
307+
# @return [Execution::NextFinalizer] `finalizer`
308+
def add_finalizer(finalizer)
309+
f = @finalizers ||= []
310+
f << finalizer
311+
f
312+
end
313+
301314
# Determine the values for variables of this query, using default values
302315
# if a value isn't provided at runtime.
303316
#

0 commit comments

Comments
 (0)