Skip to content

Commit

Permalink
Merge pull request #5217 from rmosolgo/simplify-backtrace
Browse files Browse the repository at this point in the history
Simplify GraphQL::Backtrace
  • Loading branch information
rmosolgo authored Jan 29, 2025
2 parents a466893 + 8308eb2 commit 3df9181
Show file tree
Hide file tree
Showing 14 changed files with 152 additions and 355 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
- run: bundle exec rake compile
- run: bundle exec rake test
- run: git fetch --no-tags --prune --depth=10 origin +refs/heads/*:refs/remotes/origin/*
- run: bundle exec pronto run -f github_status github_pr -c origin/${{ github.base_ref }}
- run: bundle exec pronto run -f github_pr -c origin/${{ github.base_ref }}
if: ${{ !!matrix.coverage }}
env:
PRONTO_PULL_REQUEST_ID: ${{ github.event.pull_request.number }}
Expand Down
1 change: 1 addition & 0 deletions benchmark/run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require "stackprof"
require "memory_profiler"
require "graphql/batch"
require "securerandom"

module GraphQLBenchmark
QUERY_STRING = GraphQL::Introspection::INTROSPECTION_QUERY
Expand Down
20 changes: 1 addition & 19 deletions lib/graphql/backtrace.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# frozen_string_literal: true
require "graphql/backtrace/inspect_result"
require "graphql/backtrace/table"
require "graphql/backtrace/traced_error"
require "graphql/backtrace/tracer"
require "graphql/backtrace/trace"
module GraphQL
# Wrap unhandled errors with {TracedError}.
#
Expand All @@ -24,7 +21,7 @@ class Backtrace
def_delegators :to_a, :each, :[]

def self.use(schema_defn)
schema_defn.trace_with(self::Trace)
schema_defn.using_backtrace = true
end

def initialize(context, value: nil)
Expand All @@ -40,20 +37,5 @@ def inspect
def to_a
@table.to_backtrace
end

# Used for internal bookkeeping
# @api private
class Frame
attr_reader :path, :query, :ast_node, :object, :field, :arguments, :parent_frame
def initialize(path:, query:, ast_node:, object:, field:, arguments:, parent_frame:)
@path = path
@query = query
@ast_node = ast_node
@field = field
@object = object
@arguments = arguments
@parent_frame = parent_frame
end
end
end
end
38 changes: 0 additions & 38 deletions lib/graphql/backtrace/inspect_result.rb

This file was deleted.

150 changes: 95 additions & 55 deletions lib/graphql/backtrace/table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,70 @@ def to_backtrace
private

def rows
@rows ||= build_rows(@context, rows: [HEADERS], top: true)
@rows ||= begin
query = @context.query
query_ctx = @context
runtime_inst = query_ctx.namespace(:interpreter_runtime)[:runtime]
result = runtime_inst.instance_variable_get(:@response)
rows = []
result_path = []
last_part = nil
path = @context.current_path
path.each do |path_part|
value = value_at(runtime_inst, result_path)

if result_path.empty?
name = query.selected_operation.operation_type || "query"
if (n = query.selected_operation_name)
name += " #{n}"
end
args = query.variables
else
name = result.graphql_field.path
args = result.graphql_arguments
end

object = result.graphql_parent ? result.graphql_parent.graphql_application_value : result.graphql_application_value
object = object.object.inspect

rows << [
result.ast_node.position.join(":"),
name,
"#{object}",
args.to_h.inspect,
inspect_result(value),
]

result_path << path_part
if path_part == path.last
last_part = path_part
else
result = result[path_part]
end
end


object = result.graphql_application_value.object.inspect
ast_node = result.graphql_selections.find { |s| s.alias == last_part || s.name == last_part }
field_defn = query.get_field(result.graphql_result_type, ast_node.name)
args = query.arguments_for(ast_node, field_defn).to_h
field_path = field_defn.path
if ast_node.alias
field_path += " as #{ast_node.alias}"
end

rows << [
ast_node.position.join(":"),
field_path,
"#{object}",
args.inspect,
inspect_result(@override_value)
]

rows << HEADERS
rows.reverse!
rows
end
end

# @return [String]
Expand Down Expand Up @@ -75,67 +138,44 @@ def render_table(rows)
table
end

# @return [Array] 5 items for a backtrace table (not `key`)
def build_rows(context_entry, rows:, top: false)
case context_entry
when Backtrace::Frame
field_alias = context_entry.ast_node.respond_to?(:alias) && context_entry.ast_node.alias
value = if top && @override_value
@override_value
else
value_at(@context.query.context.namespace(:interpreter_runtime)[:runtime], context_entry.path)
end
rows << [
"#{context_entry.ast_node ? context_entry.ast_node.position.join(":") : ""}",
"#{context_entry.field.path}#{field_alias ? " as #{field_alias}" : ""}",
"#{context_entry.object.object.inspect}",
context_entry.arguments.to_h.inspect, # rubocop:disable Development/ContextIsPassedCop -- unrelated method
Backtrace::InspectResult.inspect_result(value),
]
if (parent = context_entry.parent_frame)
build_rows(parent, rows: rows)
else
rows
end
when GraphQL::Query::Context
query = context_entry.query
op = query.selected_operation
if op
op_type = op.operation_type
position = "#{op.line}:#{op.col}"
else
op_type = "query"
position = "?:?"
end
op_name = query.selected_operation_name
object = query.root_value
if object.is_a?(GraphQL::Schema::Object)
object = object.object
end
value = value_at(context_entry.namespace(:interpreter_runtime)[:runtime], [])
rows << [
"#{position}",
"#{op_type}#{op_name ? " #{op_name}" : ""}",
"#{object.inspect}",
query.variables.to_h.inspect,
Backtrace::InspectResult.inspect_result(value),
]
else
raise "Unexpected get_rows subject #{context_entry.class} (#{context_entry.inspect})"
end
end

def value_at(runtime, path)
response = runtime.final_result
path.each do |key|
if response && (response = response[key])
next
else
break
end
response && (response = response[key])
end
response
end

def inspect_result(obj)
case obj
when Hash
"{" +
obj.map do |key, val|
"#{key}: #{inspect_truncated(val)}"
end.join(", ") +
"}"
when Array
"[" +
obj.map { |v| inspect_truncated(v) }.join(", ") +
"]"
else
inspect_truncated(obj)
end
end

def inspect_truncated(obj)
case obj
when Hash
"{...}"
when Array
"[...]"
when GraphQL::Execution::Lazy
"(unresolved)"
else
"#{obj.inspect}"
end
end
end
end
end
93 changes: 0 additions & 93 deletions lib/graphql/backtrace/trace.rb

This file was deleted.

Loading

0 comments on commit 3df9181

Please sign in to comment.