11from typing import Any , Callable , Dict , List , Optional , Union
22
33import graphql
4+ from graphql import located_error
45from graphql .execution .execute import get_field_def
5- from graphql .execution .values import get_variable_values
6+ from graphql .execution .values import get_argument_values , get_variable_values
7+
68from graphql .pyutils import AwaitableOrValue , FrozenList , Path , Undefined , inspect
79
810from .middleware import MiddlewareManager
911
1012
1113class ExecutionContext (graphql .ExecutionContext ):
14+ # custom Middleware Manager
1215 middleware_manager : MiddlewareManager
1316
1417 @classmethod
@@ -114,6 +117,7 @@ def resolve_field(
114117 if not field_def :
115118 return Undefined
116119
120+ return_type = field_def .type
117121 resolve_fn = field_def .resolve or self .field_resolver
118122
119123 if self .middleware_manager :
@@ -125,6 +129,48 @@ def resolve_field(
125129
126130 # Get the resolve function, regardless of if its result is normal or abrupt
127131 # (error).
128- result = self .resolve_field_value_or_error (field_def , field_nodes , resolve_fn , source , info )
129-
130- return self .complete_value_catching_error (field_def .type , field_nodes , info , path , result )
132+ try :
133+ # Build a dictionary of arguments from the field.arguments AST, using the
134+ # variables scope to fulfill any variable references.
135+ args = get_argument_values (field_def , field_nodes [0 ], self .variable_values )
136+
137+ # Note that contrary to the JavaScript implementation, we pass the context
138+ # value as part of the resolve info.
139+ result = resolve_fn (source , info , ** args )
140+
141+ completed : AwaitableOrValue [Any ]
142+ if self .is_awaitable (result ):
143+ # noinspection PyShadowingNames
144+ async def await_result () -> Any :
145+ try :
146+ completed = self .complete_value (
147+ return_type , field_nodes , info , path , await result
148+ )
149+ if self .is_awaitable (completed ):
150+ return await completed
151+ return completed
152+ except Exception as raw_error :
153+ error = located_error (raw_error , field_nodes , path .as_list ())
154+ self .handle_field_error (error , return_type )
155+ return None
156+
157+ return await_result ()
158+
159+ completed = self .complete_value (return_type , field_nodes , info , path , result )
160+ if self .is_awaitable (completed ):
161+ # noinspection PyShadowingNames
162+ async def await_completed () -> Any :
163+ try :
164+ return await completed
165+ except Exception as raw_error :
166+ error = located_error (raw_error , field_nodes , path .as_list ())
167+ self .handle_field_error (error , return_type )
168+ return None
169+
170+ return await_completed ()
171+
172+ return completed
173+ except Exception as raw_error :
174+ error = located_error (raw_error , field_nodes , path .as_list ())
175+ self .handle_field_error (error , return_type )
176+ return None
0 commit comments