Skip to content

Commit

Permalink
Merge pull request #4708 from rmosolgo/fix-backtrace-with-defer
Browse files Browse the repository at this point in the history
Fix { backtrace: true } with @defer
  • Loading branch information
rmosolgo authored Nov 21, 2023
2 parents b8948d5 + 952d30c commit d56c773
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 17 deletions.
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

0 comments on commit d56c773

Please sign in to comment.