Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix { backtrace: true } with @defer #4708

Merged
merged 2 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions lib/graphql/backtrace/trace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
module GraphQL
class Backtrace
module Trace
def initialize(*args, **kwargs, &block)
@__backtrace_contexts = {}
@__backtrace_last_context = nil
super
end

def validate(query:, validate:)
if query.multiplex
push_query_backtrace_context(query)
Expand Down Expand Up @@ -42,36 +48,27 @@ def execute_multiplex(multiplex:)
rescue StandardError => err
# This is an unhandled error from execution,
# Re-raise it with a GraphQL trace.
multiplex_context = multiplex.context
potential_context = multiplex_context[:last_graphql_backtrace_context]

potential_context = @__backtrace_last_context
if potential_context.is_a?(GraphQL::Query::Context) ||
potential_context.is_a?(Backtrace::Frame)
raise TracedError.new(err, potential_context)
else
raise
end
ensure
multiplex_context = multiplex.context
multiplex_context.delete(:graphql_backtrace_contexts)
multiplex_context.delete(:last_graphql_backtrace_context)
end

private

def push_query_backtrace_context(query)
push_data = query
multiplex = query.multiplex
push_key = []
push_storage = multiplex.context[:graphql_backtrace_contexts] ||= {}
push_storage[push_key] = push_data
multiplex.context[:last_graphql_backtrace_context] = push_data
@__backtrace_contexts[push_key] = push_data
@__backtrace_last_context = push_data
end

def push_field_backtrace_context(field, query, ast_node, arguments, object)
multiplex = query.multiplex
push_key = query.context[:current_path]
push_storage = multiplex.context[:graphql_backtrace_contexts]
push_storage = @__backtrace_contexts
parent_frame = push_storage[push_key[0..-2]]

if parent_frame.is_a?(GraphQL::Query)
Expand All @@ -87,10 +84,10 @@ def push_field_backtrace_context(field, query, ast_node, arguments, object)
arguments: arguments,
parent_frame: parent_frame,
)

push_storage[push_key] = push_data
multiplex.context[:last_graphql_backtrace_context] = push_data
@__backtrace_last_context = push_data
end

end
end
end
2 changes: 0 additions & 2 deletions lib/graphql/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ def initialize(schema, query_string = nil, query: nil, document: nil, context: n
if schema.trace_class <= GraphQL::Tracing::CallLegacyTracers
context_tracers += [GraphQL::Backtrace::Tracer]
@tracers << GraphQL::Backtrace::Tracer
elsif !(current_trace.class <= GraphQL::Backtrace::Trace)
raise "Invariant: `backtrace: true` should have provided a trace class with Backtrace mixed in, but it didnt. (Found: #{current_trace.class.ancestors}). This is a bug in GraphQL-Ruby, please report it on GitHub."
end
end

Expand Down