From 52061b8fa6607cfc309401ffa1a5bb34a6134428 Mon Sep 17 00:00:00 2001 From: Markus Padourek Date: Thu, 28 Apr 2016 15:42:07 +0100 Subject: [PATCH] Revert imports and add raise with original stack trace. --- graphql/core/error/__init__.py | 3 +++ .../core/{error.py => error/graphql_error.py} | 14 +++++-------- graphql/core/execution/executor.py | 20 +++++++++++++++++-- .../validation/rules/unique_argument_names.py | 2 +- .../rules/unique_operation_names.py | 2 +- .../rules/variables_are_input_types.py | 2 +- tests/core_execution/test_executor.py | 2 +- tests/core_execution/test_variables.py | 2 +- tests/core_utils/test_extend_schema.py | 1 + 9 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 graphql/core/error/__init__.py rename graphql/core/{error.py => error/graphql_error.py} (79%) diff --git a/graphql/core/error/__init__.py b/graphql/core/error/__init__.py new file mode 100644 index 00000000..1e687282 --- /dev/null +++ b/graphql/core/error/__init__.py @@ -0,0 +1,3 @@ +from .graphql_error import GraphQLError, format_error + +__all__ = ['GraphQLError', 'format_error'] diff --git a/graphql/core/error.py b/graphql/core/error/graphql_error.py similarity index 79% rename from graphql/core/error.py rename to graphql/core/error/graphql_error.py index 9308eb42..f14831ee 100644 --- a/graphql/core/error.py +++ b/graphql/core/error/graphql_error.py @@ -1,20 +1,16 @@ -from .language.location import get_location +from ..language.location import get_location -class Error(Exception): - pass +class GraphQLError(Exception): + __slots__ = 'message', 'nodes', '_source', '_positions', 'original_error' - -class GraphQLError(Error): - __slots__ = 'message', 'nodes', 'stack', '_source', '_positions' - - def __init__(self, message, nodes=None, stack=None, source=None, positions=None): + def __init__(self, message, nodes=None, source=None, positions=None, original_error=None): super(GraphQLError, self).__init__(message) self.message = message or 'An unknown error occurred.' self.nodes = nodes - self.stack = stack or message self._source = source self._positions = positions + self.original_error = original_error @property def source(self): diff --git a/graphql/core/execution/executor.py b/graphql/core/execution/executor.py index 92aec6b3..fd14b69b 100644 --- a/graphql/core/execution/executor.py +++ b/graphql/core/execution/executor.py @@ -1,5 +1,8 @@ import collections import functools +import sys + +from six import reraise from ..error import GraphQLError from ..language import ast @@ -17,6 +20,14 @@ get_operation_root_type) +def _raise_with_original_stack_trace(original_error, new_error_type, new_error): + try: + raise original_error + except: + _, __, original_traceback = sys.exc_info() + reraise(new_error_type, new_error, original_traceback) + + class Executor(object): def __init__(self, execution_middlewares=None, default_resolver=default_resolve_fn, map_type=dict): @@ -227,11 +238,16 @@ def complete_value(self, ctx, return_type, field_asts, info, result): info, resolved ), - lambda error: GraphQLError(error.value and str(error.value), field_asts, error) + lambda error: _raise_with_original_stack_trace( + error, + GraphQLError, + GraphQLError(error.value and str(error.value), field_asts, original_error=error) + ) ) if isinstance(result, Exception): - raise GraphQLError(str(result), field_asts, result) + _raise_with_original_stack_trace( + result, GraphQLError, GraphQLError(result.message or str(result), field_asts, original_error=result)) if isinstance(return_type, GraphQLNonNull): completed = self.complete_value( diff --git a/graphql/core/validation/rules/unique_argument_names.py b/graphql/core/validation/rules/unique_argument_names.py index 9e25c75c..6bc601d2 100644 --- a/graphql/core/validation/rules/unique_argument_names.py +++ b/graphql/core/validation/rules/unique_argument_names.py @@ -1,4 +1,4 @@ -from ...error import GraphQLError +from ...error.graphql_error import GraphQLError from .base import ValidationRule diff --git a/graphql/core/validation/rules/unique_operation_names.py b/graphql/core/validation/rules/unique_operation_names.py index 1fccbb9b..e8171c6e 100644 --- a/graphql/core/validation/rules/unique_operation_names.py +++ b/graphql/core/validation/rules/unique_operation_names.py @@ -1,4 +1,4 @@ -from ...error import GraphQLError +from ...error.graphql_error import GraphQLError from .base import ValidationRule diff --git a/graphql/core/validation/rules/variables_are_input_types.py b/graphql/core/validation/rules/variables_are_input_types.py index f510fbba..54df04b1 100644 --- a/graphql/core/validation/rules/variables_are_input_types.py +++ b/graphql/core/validation/rules/variables_are_input_types.py @@ -1,4 +1,4 @@ -from ...error import GraphQLError +from ...error.graphql_error import GraphQLError from ...language.printer import print_ast from ...type.definition import is_input_type from ...utils.type_from_ast import type_from_ast diff --git a/tests/core_execution/test_executor.py b/tests/core_execution/test_executor.py index 2e252694..02a51ae6 100644 --- a/tests/core_execution/test_executor.py +++ b/tests/core_execution/test_executor.py @@ -3,7 +3,7 @@ from pytest import raises -from graphql.core.error import GraphQLError +from graphql.core.error.graphql_error import GraphQLError from graphql.core.execution import Executor, execute from graphql.core.execution.middlewares.sync import \ SynchronousExecutionMiddleware diff --git a/tests/core_execution/test_variables.py b/tests/core_execution/test_variables.py index 72745a36..f52d943f 100644 --- a/tests/core_execution/test_variables.py +++ b/tests/core_execution/test_variables.py @@ -2,7 +2,7 @@ from pytest import raises -from graphql.core.error import GraphQLError, format_error +from graphql.core.error.graphql_error import GraphQLError, format_error from graphql.core.execution import execute from graphql.core.language.parser import parse from graphql.core.type import (GraphQLArgument, GraphQLField, diff --git a/tests/core_utils/test_extend_schema.py b/tests/core_utils/test_extend_schema.py index c5db47ce..19c87a16 100644 --- a/tests/core_utils/test_extend_schema.py +++ b/tests/core_utils/test_extend_schema.py @@ -102,6 +102,7 @@ def test_cannot_be_used_for_execution(): clientQuery = parse('{ newField }') result = execute(extended_schema, object(), clientQuery) + print(result) assert result.data['newField'] is None assert str(result.errors[0] ) == 'Client Schema cannot be used for execution.'