diff --git a/graphql/execution/base.py b/graphql/execution/base.py index 7929cd5a..c013d6eb 100644 --- a/graphql/execution/base.py +++ b/graphql/execution/base.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import sys from ..error import GraphQLError from ..language import ast from ..pyutils.default_ordered_dict import DefaultOrderedDict @@ -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 diff --git a/graphql/execution/executor.py b/graphql/execution/executor.py index 202ba981..797c2fd7 100644 --- a/graphql/execution/executor.py +++ b/graphql/execution/executor.py @@ -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) @@ -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() @@ -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 diff --git a/graphql/execution/executors/utils.py b/graphql/execution/executors/utils.py index 4fc44875..38f39eeb 100644 --- a/graphql/execution/executors/utils.py +++ b/graphql/execution/executors/utils.py @@ -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)