module GraphQL::Backtrace::Trace

def analyze_query(query:)

def analyze_query(query:)
  if query.multiplex # missing for stand-alone static validation
    push_query_backtrace_context(query)
  end
  super
end

def execute_field(field:, query:, ast_node:, arguments:, object:)

def execute_field(field:, query:, ast_node:, arguments:, object:)
  push_field_backtrace_context(field, query, ast_node, arguments, object)
  super
end

def execute_field_lazy(field:, query:, ast_node:, arguments:, object:)

def execute_field_lazy(field:, query:, ast_node:, arguments:, object:)
  push_field_backtrace_context(field, query, ast_node, arguments, object)
  super
end

def execute_multiplex(multiplex:)

def execute_multiplex(multiplex:)
  super
rescue StandardError => err
  # This is an unhandled error from execution,
  # Re-raise it with a GraphQL trace.
  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
end

def execute_query(query:)

def execute_query(query:)
  push_query_backtrace_context(query)
  super
end

def execute_query_lazy(query:, multiplex:)

def execute_query_lazy(query:, multiplex:)
  query ||= multiplex.queries.first
  push_query_backtrace_context(query)
  super
end

def initialize(*args, **kwargs, &block)

def initialize(*args, **kwargs, &block)
  @__backtrace_contexts = {}
  @__backtrace_last_context = nil
  super
end

def push_field_backtrace_context(field, query, ast_node, arguments, object)

def push_field_backtrace_context(field, query, ast_node, arguments, object)
  push_key = query.context[:current_path]
  push_storage = @__backtrace_contexts
  parent_frame = push_storage[push_key[0..-2]]
  if parent_frame.is_a?(GraphQL::Query)
    parent_frame = parent_frame.context
  end
  push_data = Frame.new(
    query: query,
    path: push_key,
    ast_node: ast_node,
    field: field,
    object: object,
    arguments: arguments,
    parent_frame: parent_frame,
  )
  push_storage[push_key] = push_data
  @__backtrace_last_context = push_data
end

def push_query_backtrace_context(query)

def push_query_backtrace_context(query)
  push_data = query
  push_key = []
  @__backtrace_contexts[push_key] = push_data
  @__backtrace_last_context = push_data
end

def validate(query:, validate:)

def validate(query:, validate:)
  if query.multiplex
    push_query_backtrace_context(query)
  end
  super
end