Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add error stacktraces to 1.1.0 #221

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions graphql/execution/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import sys
from ..error import GraphQLError
from ..language import ast
from ..pyutils.default_ordered_dict import DefaultOrderedDict
Expand Down Expand Up @@ -67,6 +68,10 @@ def __init__(self, schema, document_ast, root_value, context_value, variable_val
self.middleware = middleware
self._subfields_cache = {}

def report_error(self, error, traceback=None):
sys.excepthook(type(error), str(error), getattr(error, 'stack', None) or traceback)
self.errors.append(error)

def get_field_resolver(self, field_resolver):
if not self.middleware:
return field_resolver
Expand Down
12 changes: 7 additions & 5 deletions graphql/execution/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ def execute(schema, document_ast, root_value=None, context_value=None,
middleware
)

def executor(resolve, reject):
return resolve(execute_operation(context, context.operation, root_value))
def executor(v):
return execute_operation(context, context.operation, root_value)

def on_rejected(error):
context.errors.append(error)
Expand All @@ -75,7 +75,7 @@ def on_resolve(data):
return ExecutionResult(data=data)
return ExecutionResult(data=data, errors=context.errors)

promise = Promise(executor).catch(on_rejected).then(on_resolve)
promise = Promise.resolve(None).then(executor).catch(on_rejected).then(on_resolve)
if return_promise:
return promise
context.executor.wait_until_finished()
Expand Down Expand Up @@ -218,14 +218,16 @@ def complete_value_catching_error(exe_context, return_type, field_asts, info, re
completed = complete_value(exe_context, return_type, field_asts, info, result)
if is_thenable(completed):
def handle_error(error):
exe_context.errors.append(error)
traceback = completed._traceback
exe_context.report_error(error, traceback)
return None

return completed.catch(handle_error)

return completed
except Exception as e:
exe_context.errors.append(e)
traceback = sys.exc_info()[2]
exe_context.report_error(e, traceback)
return None


Expand Down
6 changes: 5 additions & 1 deletion graphql/execution/executors/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from sys import exc_info

def process(p, f, args, kwargs):
try:
val = f(*args, **kwargs)
p.do_resolve(val)
except Exception as e:
p.do_reject(e)
traceback = exc_info()[2]
e.stack = traceback
p.do_reject(e, traceback=traceback)