1from typing import Any, Dict, List, Optional 2 3 4class SkipCollection(Exception): 5 pass 6 7 8class TartifletteError(Exception): 9 """ 10 Base exceptions of all internal errors raised by the Tartiflette engine. 11 """ 12 13 def __init__( 14 self, 15 message: str, 16 path: Optional[List[str]] = None, 17 locations: Optional[List["Location"]] = None, 18 user_message: Optional[str] = None, 19 more_info: Optional[str] = None, 20 extensions: Optional[Dict[str, Any]] = None, 21 original_error: Optional[Exception] = None, 22 ) -> None: 23 """ 24 :param message: message explaining the error which occurred 25 :param path: path on the query where the error occurred 26 :param locations: locations on the document where the error occurred 27 :param user_message: more detailed human message explaining the error 28 :param more_info: extra information for the error 29 :param extensions: extra information for the error which will be added 30 to the `extensions` key once coerced 31 :param original_error: instance of the original exception which lead to 32 the error 33 :type message: str 34 :type path: Optional[List[str]] 35 :type locations: Optional[List[Location]] 36 :type user_message: Optional[str] 37 :type more_info: Optional[str] 38 :type extensions: Optional[Dict[str, Any]] 39 :type original_error: Optional[Exception] 40 """ 41 super().__init__(message) 42 self.message = message # Developer message by default 43 self.user_message = user_message 44 self.more_info = more_info or "" 45 self.path = path or None 46 self.locations = locations or [] 47 self.extensions = extensions or {} 48 self.original_error = original_error 49 50 def __repr__(self) -> str: 51 """ 52 Returns the representation of a TartifletteError instance. 53 :return: the representation of a TartifletteError instance 54 :rtype: str 55 """ 56 return f"{self.__class__.__name__}(message=%r, locations=%r)" % ( 57 self.user_message or self.message, 58 self.locations, 59 ) 60 61 def coerce_value( 62 self, 63 *_args, 64 path: Optional[List[str]] = None, 65 locations: Optional[List["Location"]] = None, 66 **_kwargs, 67 ) -> Dict[str, Any]: 68 """ 69 Converts the TartifletteError instance into a valid GraphQL error 70 output. 71 :param path: path on the query where the error occurred 72 :param locations: locations on the document where the error occurred 73 :type path: Optional[List[str]] 74 :type locations: Optional[List[Location]] 75 :return: a valid GraphQL error output 76 :rtype: Dict[str, Any] 77 """ 78 # pylint: disable=missing-param-doc 79 computed_locations = [] 80 81 try: 82 for location in locations or self.locations: 83 computed_locations.append(location.collect_value()) 84 except (AttributeError, TypeError): 85 pass 86 87 errors = { 88 "message": self.user_message or self.message, 89 "path": path or self.path, 90 "locations": computed_locations, 91 } 92 93 if self.extensions: 94 errors["extensions"] = dict(self.extensions) 95 return errors 96 97 98class MultipleException(Exception): 99 """ 100 Utility exception which allows to handle multiple errors at once. 101 """ 102 103 def __init__(self, exceptions: Optional[List[Exception]] = None) -> None: 104 """ 105 :param exceptions: list of exceptions to handle 106 :type exceptions: Optional[List[Exception]] 107 """ 108 super().__init__() 109 self.exceptions = exceptions or [] 110 111 def __bool__(self) -> bool: 112 """ 113 Determines whether or not there is exceptions. 114 :return: whether or not there is exceptions 115 :rtype: bool 116 """ 117 return bool(self.exceptions) 118 119 def __add__(self, other: "MultipleException") -> "MultipleException": 120 """ 121 Concatenates the exception list of both MultipleException to return a 122 new MultipleException instance containing both exception list. 123 :param other: an MultipleException instance 124 :type other: MultipleException 125 :return: a new MultipleException containing both exception list 126 :rtype: MultipleException 127 """ 128 return MultipleException(self.exceptions + other.exceptions) 129 130 131class ImproperlyConfigured(TartifletteError): 132 pass 133 134 135class InvalidType(TartifletteError): 136 pass 137 138 139class GraphQLSchemaError(TartifletteError): 140 pass 141 142 143class GraphQLSyntaxError(TartifletteError): 144 pass 145 146 147class NonCallable(ImproperlyConfigured): 148 pass 149 150 151class NonCoroutine(ImproperlyConfigured): 152 pass 153 154 155class NonAwaitableResolver(ImproperlyConfigured): 156 pass 157 158 159class NonAsyncGeneratorSubscription(ImproperlyConfigured): 160 pass 161 162 163class NotSubscriptionField(ImproperlyConfigured): 164 pass 165 166 167class UnknownSchemaFieldResolver(TartifletteError): 168 pass 169 170 171class UnknownDirectiveDefinition(TartifletteError): 172 pass 173 174 175class UnknownScalarDefinition(TartifletteError): 176 pass 177 178 179class UnknownFieldDefinition(TartifletteError): 180 pass 181 182 183class UnknownTypeDefinition(TartifletteError): 184 pass 185 186 187class MissingImplementation(ImproperlyConfigured): 188 pass 189 190 191class RedefinedImplementation(TartifletteError): 192 pass 193 194 195class CoercionError(TartifletteError): 196 pass 197