Backtrace Annotations
context objects have a backtrace which shows its GraphQL context. You can print the backtrace during query execution:
puts context.backtrace # Loc | Field | Object | Arguments | Result # 3:13 | User.login | #<User id=1> | {"message"=>"Boom"} | #<RuntimeError: This is broken: Boom> # 2:11 | Query.user | nil | {"login"=>"rmosolgo"} | {} # 1:9 | query | nil | {"msg"=>"Boom"} |
The backtrace contains some execution data:
-
Locis theline:columnof the field in the query string -
Fieldis theTypeName.fieldNameof the fields in the backtrace -
Objectis theobjfor query resolution (used for resolving the given field), equivalent toobj.inspect -
Argumentsare theGraphQLarguments for field resolution (including any default values and variable values) -
Resultis the GraphQL-ready result which is being constructed (it may be incomplete if the query is still in-progress)
Wrapping Errors
You can wrap unhandled errors with a GraphQL error with GraphQL::Backtrace.
To enable this feature for a query, add backtrace: true to your context, for example:
# Wrap this query with backtrace annotation MySchema.execute(query_string, context: { backtrace: true })
Or, to always wrap backtraces, add it to your schema definition with use, for example:
class MySchema < GraphQL::Schema # Always wrap backtraces with GraphQL annotation use GraphQL::Backtrace end
Now, any unhandled errors will be wrapped by GraphQL::Backtrace::TracedError, which prints out the GraphQL backtrace, too. For example:
Unhandled error during GraphQL execution:
This is broken: Boom
/Users/rmosolgo/code/graphql-ruby/spec/graphql/backtrace_spec.rb:27:in `block (3 levels) in <top (required)>'
/Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/build_from_definition/resolve_map.rb:57:in `call'
/Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/build_from_definition.rb:171:in `block in build_object_type'
/Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/build_from_definition.rb:280:in `block (2 levels) in build_fields'
/Users/rmosolgo/code/graphql-ruby/lib/graphql/field.rb:228:in `resolve'
/Users/rmosolgo/code/graphql-ruby/lib/graphql/execution/execute.rb:253:in `call'
/Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/middleware_chain.rb:45:in `invoke_core'
/Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/middleware_chain.rb:38:in `invoke'
/Users/rmosolgo/code/graphql-ruby/lib/graphql/execution/execute.rb:107:in `resolve_field'
/Users/rmosolgo/code/graphql-ruby/lib/graphql/execution/execute.rb:71:in `block (2 levels) in resolve_selection'
... and 65 more lines
Use #cause to access the original exception (including #cause.backtrace).
GraphQL Backtrace:
Loc | Field | Object | Arguments | Result
3:13 | Thing.raiseField as boomError | :something | {"message"=>"Boom"} | #<RuntimeError: This is broken: Boom>
2:11 | Query.field1 | "Root" | {} | {}
1:9 | query | "Root" | {"msg"=>"Boom"} | {}