async def __type_resolver( parent: Optional[Any], args: Dict[str, Any], ctx: Optional[Any], info: "ResolveInfo", ) -> "GraphQLType": """ Callable to use to resolve the `__type` field. :param parent: default root value or field parent value :param args: computed arguments related to the resolved field :param ctx: context passed to the query execution :param info: information related to the execution and the resolved field :type parent: Optional[Any] :type args: Dict[str, Any] :type ctx: Optional[Any] :type info: ResolveInfo :return: the computed field value :rtype: GraphQLType """ # pylint: disable=unused-argument if not info.schema.is_introspectable: raise TartifletteError("Introspection is disabled for this schema") info.is_introspection = True try: return info.schema.find_type(args["name"]) except KeyError: pass return None
def add_error( self, raw_exception: Union["TartifletteError", "MultipleException", Exception], path: Optional[List[str]] = None, locations: Optional[List["Location"]] = None, ) -> None: """ Adds the contents of an exception to the known execution errors. :param raw_exception: the raw exception to treat :param path: the path where the raw exception occurred :param locations: the locations linked to the raw exception :type raw_exception: Union[TartifletteError, MultipleException, Exception] :type path: Optional[List[str]] :param locations: Optional[List["Location"]] """ exceptions = (raw_exception.exceptions if isinstance( raw_exception, MultipleException) else [raw_exception]) for exception in exceptions: graphql_error = ( exception if is_coercible_exception(exception) else TartifletteError( str(exception), path, locations, original_error=exception)) self.errors.append(graphql_error)
async def create_source_event_stream( self, execution_ctx: ExecutionContext, request_ctx: Optional[Dict[str, Any]], parent_result: Optional[Any] = None, ): if not self.subscribe: raise TartifletteError( "Can't execute a subscription query on a field which doesn't " "provide a source event stream with < @Subscription >.") info = Info( query_field=self, schema_field=self.field_executor.schema_field, schema=self.schema, path=self.path, location=self.location, execution_ctx=execution_ctx, ) return self.subscribe( parent_result, await coerce_arguments( self.field_executor.schema_field.arguments, self.arguments, request_ctx, info, ), request_ctx, info, )
async def execute( self, query: Union[str, bytes], operation_name: Optional[str] = None, context: Optional[Any] = None, variables: Optional[Dict[str, Any]] = None, initial_value: Optional[Any] = None, ) -> Dict[str, Any]: """ Parses and executes a GraphQL query/mutation request. :param query: the GraphQL request / query as UTF8-encoded string :param operation_name: the operation name to execute :param context: value that can contain everything you need and that will be accessible from the resolvers :param variables: the variables provided in the GraphQL request :param initial_value: an initial value corresponding to the root type being executed :type query: Union[str, bytes] :type operation_name: Optional[str] :type context: Optional[Any] :type variables: Optional[Dict[str, Any]] :type initial_value: Optional[Any] :return: computed response corresponding to the request :rtype: Dict[str, Any] """ document, errors = self._cached_parse_and_validate_query( query, self._schema) # Goes through potential schema directives and finish in self._perform_query try: return await self._query_executor( self._schema, document, errors, operation_name, context, variables, initial_value, context_coercer=context, ) # pylint: disable=broad-except except Exception as e: if not isinstance(e, TartifletteError): e = TartifletteError( message=str(e), path=[self._schema.query_operation_name], original_error=e, ) return await self._build_response(errors=[e])
def to_graphql_error( raw_exception: Exception, message: Optional[str] = None) -> Union["TartifletteError", Exception]: """ Converts the raw exception into a TartifletteError if its not coercible or returns the raw exception if coercible. :param raw_exception: the raw exception to be treated :param message: message replacing the raw exception message when it's not coercible :type raw_exception: Exception :type message: Optional[str] :return: a coercible exception :rtype: Union["TartifletteError", Exception] """ return (raw_exception if is_coercible_exception(raw_exception) else TartifletteError(message or str(raw_exception), original_error=raw_exception))
def _add_errors_to_execution_context( execution_context: ExecutionContext, raw_exception: Union[Exception, MultipleException], path: Union[str, List[str]], location: "Location", ) -> None: exceptions = (raw_exception.exceptions if isinstance( raw_exception, MultipleException) else [raw_exception]) for exception in exceptions: gql_error = (exception if is_coercible_exception(exception) else TartifletteError(str(exception), path, [location], original_error=exception)) gql_error.coerce_value = partial(gql_error.coerce_value, path=path, locations=[location]) execution_context.add_error(gql_error)
def graphql_error_from_nodes( message: str, nodes: Union["Node", List["Node"]], path: Optional[Union[List[str], "Path"]] = None, original_error: Optional[Exception] = None, extensions: Optional[Dict[str, Any]] = None, ) -> "TartifletteError": """ Returns a TartifletteError linked to a list of AST nodes which make it possible to fill in the location of the error. :param message: error message :param nodes: AST nodes to link to the error :param path: the path where the original exception occurred :param original_error: the original raised exception :param extensions: Extensions dict to add to the error. :type message: str :type nodes: Union[Node, List[Node]] :type path: Optional[List[str]] :type original_error: Optional[Exception] :type extensions: Optional[Dict[str, Any]] :return: a TartifletteError with locations :rtype: TartifletteError """ if not isinstance(nodes, list): nodes = [nodes] if isinstance(path, Path): path = path.as_list() return TartifletteError( message, locations=[node.location for node in nodes], path=path, original_error=original_error, extensions=extensions, )
async def build_execution_context( schema: "GraphQLSchema", document: "DocumentNode", root_value: Optional[Any], context: Optional[Any], raw_variable_values: Optional[Dict[str, Any]], operation_name: str, ) -> Tuple[Optional["ExecutionContext"], Optional[List["TartifletteError"]]]: """ Factory function to build and return an ExecutionContext instance. :param schema: the GraphQLSchema instance linked to the engine :param document: the DocumentNode instance linked to the GraphQL request :param root_value: an initial value corresponding to the root type being executed :param context: value that can contain everything you need and that will be accessible from the resolvers :param raw_variable_values: the variables provided in the GraphQL request :param operation_name: the operation name to execute :type schema: GraphQLSchema :type document: DocumentNode :type root_value: Optional[Any] :type context: Optional[Any] :type raw_variable_values: Optional[Dict[str, Any]] :type operation_name: str :return: an ExecutionContext instance :rtype: Tuple[Optional[ExecutionContext], Optional[List[TartifletteError]]] """ # pylint: disable=too-many-arguments,too-many-locals,too-complex errors: List["TartifletteError"] = [] operation: Optional["OperationDefinitionNode"] = None fragments: Dict[str, "FragmentDefinitionNode"] = {} operations: Dict[Optional[str], "OperationDefinitionNode"] = {} for definition in document.definitions: if isinstance(definition, OperationDefinitionNode): operations[definition.name.value if definition. name else None] = definition else: fragments[definition.name.value] = definition if operation_name: operation = operations.get(operation_name) elif len(operations) == 1: _, operation = operations.popitem() if not operation: errors.append( TartifletteError( f"Unknown operation named < {operation_name} >." if operation_name else "Must provide operation name if query contains multiple operations." )) variable_values: Dict[str, Any] = {} if operation: executable_variable_definitions = collect_executable_variable_definitions( schema, operation) variable_values, variable_errors = await coerce_variables( executable_variable_definitions, raw_variable_values or {}, context) if variable_errors: errors.extend(variable_errors) if errors: return None, errors return ( ExecutionContext( schema=schema, fragments=fragments, operation=operation, context=context, root_value=root_value, variable_values=variable_values, ), None, )
async def my_execute(_, exec_ctx, *__, **___): exec_ctx.add_error(TartifletteError("My error"))
def to_graphql_error(exception, message=None): if is_coercible_exception(exception): return exception return TartifletteError(message or str(exception), original_error=exception)