File: trace.rb

package info (click to toggle)
ruby-graphql 2.2.17-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,584 kB
  • sloc: ruby: 67,505; ansic: 1,753; yacc: 831; javascript: 331; makefile: 6
file content (93 lines) | stat: -rw-r--r-- 2,555 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# frozen_string_literal: true
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)
        end
        super
      end

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

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

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

      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:)
        push_field_backtrace_context(field, query, ast_node, arguments, object)
        super
      end

      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

      private

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

      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

    end
  end
end