From 3d92cd70551f840878cdcc62d5152f1f5d220fda Mon Sep 17 00:00:00 2001 From: Robert Mosolgo Date: Wed, 13 May 2026 15:03:23 -0400 Subject: [PATCH 1/2] Backtrace: fix loop when error preparing arguments --- lib/graphql/backtrace/table.rb | 11 +++++- .../execution/interpreter/arguments_cache.rb | 3 ++ spec/graphql/backtrace_spec.rb | 39 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/lib/graphql/backtrace/table.rb b/lib/graphql/backtrace/table.rb index db279c39e32..04a60769d59 100644 --- a/lib/graphql/backtrace/table.rb +++ b/lib/graphql/backtrace/table.rb @@ -90,7 +90,16 @@ def rows if ast_node field_defn = query.get_field(result.graphql_result_type, ast_node.name) - args = query.arguments_for(ast_node, field_defn).to_h + args = begin + if (cached_args = query.arguments_cache.cached_arguments_for(ast_node, field_defn)) + cached_args.to_h + else + EmptyObjects::EMPTY_HASH + end + rescue StandardError => err + "Failed to load arguments, #{err.class}: #{err.message}" + end + field_path = field_defn.path if ast_node.alias field_path += " as #{ast_node.alias}" diff --git a/lib/graphql/execution/interpreter/arguments_cache.rb b/lib/graphql/execution/interpreter/arguments_cache.rb index 92cd9ab7141..ec5482d865a 100644 --- a/lib/graphql/execution/interpreter/arguments_cache.rb +++ b/lib/graphql/execution/interpreter/arguments_cache.rb @@ -30,7 +30,10 @@ def fetch(ast_node, argument_owner, parent_object) @storage[argument_owner][parent_object][ast_node] = resolved_args end end + end + def cached_arguments_for(ast_node, argument_owner) + @storage[argument_owner][nil][ast_node] end # @yield [Interpreter::Arguments, Lazy] The finally-loaded arguments diff --git a/spec/graphql/backtrace_spec.rb b/spec/graphql/backtrace_spec.rb index 25498efc2dd..c54bf7f1346 100644 --- a/spec/graphql/backtrace_spec.rb +++ b/spec/graphql/backtrace_spec.rb @@ -375,4 +375,43 @@ def greeting(name:) assert_equal ["name is too short (minimum is 5)"], ValidatorBacktraceSchema.execute("{ greeting(name: \"Tim\") }")["errors"].map { |e| e["message"] } end end + + + describe "when prepare fails as in https://github.com/rmosolgo/graphql-ruby/issues/5627" do + class BacktracePrepareErrorSchema < GraphQL::Schema + class CreateComment < GraphQL::Schema::RelayClassicMutation + argument :author_id, String, as: :author, prepare: :prepare_author + argument :body, String + + field :comment_id, String + + def self.prepare_author(id, _ctx) + raise "Author #{id} not found" + end + + def resolve(author:, body:) + { comment_id: "new-comment" } + end + end + + class Mutation < GraphQL::Schema::Object + field :create_comment, mutation: CreateComment + end + + use GraphQL::Backtrace + mutation Mutation + end + + it "works" do + assert_raises GraphQL::Backtrace::TracedError do + BacktracePrepareErrorSchema.execute <<~GRAPHQL + mutation { + createComment(input: { authorId: "unknown", body: "hello" }) { + commentId + } + } + GRAPHQL + end + end + end end From 357251cd83ce9152fc95f0404a72511c1e128d89 Mon Sep 17 00:00:00 2001 From: Robert Mosolgo Date: Wed, 13 May 2026 15:04:11 -0400 Subject: [PATCH 2/2] Skip on exec-next --- spec/graphql/backtrace_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/graphql/backtrace_spec.rb b/spec/graphql/backtrace_spec.rb index c54bf7f1346..c5a8f502c44 100644 --- a/spec/graphql/backtrace_spec.rb +++ b/spec/graphql/backtrace_spec.rb @@ -403,6 +403,7 @@ class Mutation < GraphQL::Schema::Object end it "works" do + skip_with_exec_next assert_raises GraphQL::Backtrace::TracedError do BacktracePrepareErrorSchema.execute <<~GRAPHQL mutation {