Skip to content

Commit 4458041

Browse files
committed
feat: made exception have operation inside
1 parent 4234024 commit 4458041

File tree

4 files changed

+34
-11
lines changed

4 files changed

+34
-11
lines changed

rath/links/aiohttp.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ class AIOHttpLink(AsyncTerminatingLink):
3939

4040
endpoint_url: str
4141
"""endpoint_url is the URL to send operations to."""
42-
ssl_context: SSLContext = Field(default_factory=lambda: ssl.create_default_context(cafile=certifi.where()))
42+
ssl_context: SSLContext = Field(
43+
default_factory=lambda: ssl.create_default_context(cafile=certifi.where())
44+
)
4345
"""ssl_context is the SSLContext to use for the aiohttp session. By default, this
4446
is a context that uses the certifi CA bundle."""
4547

@@ -105,7 +107,9 @@ async def aexecute(self, operation: Operation) -> AsyncIterator[GraphQLResult]:
105107
payload: Payload = {"query": operation.document}
106108

107109
if operation.node.operation == OperationType.SUBSCRIPTION:
108-
raise NotImplementedError("Aiohttp Transport does not support subscriptions")
110+
raise NotImplementedError(
111+
"Aiohttp Transport does not support subscriptions"
112+
)
109113

110114
if len(operation.context.files.items()) > 0:
111115
payload["variables"] = operation.variables
@@ -120,7 +124,9 @@ async def aexecute(self, operation: Operation) -> AsyncIterator[GraphQLResult]:
120124
file_streams = {str(i): files[path] for i, path in enumerate(files)}
121125
operations_str = json.dumps(payload, cls=self.json_encoder)
122126

123-
data.add_field("operations", operations_str, content_type="application/json")
127+
data.add_field(
128+
"operations", operations_str, content_type="application/json"
129+
)
124130
file_map_str = json.dumps(file_map)
125131
data.add_field("map", file_map_str, content_type="application/json")
126132

@@ -141,17 +147,25 @@ async def aexecute(self, operation: Operation) -> AsyncIterator[GraphQLResult]:
141147
connector=aiohttp.TCPConnector(ssl=self.ssl_context),
142148
json_serialize=lambda x: json.dumps(x, cls=self.json_encoder),
143149
) as session:
144-
async with session.post(self.endpoint_url, headers=operation.context.headers, **post_kwargs) as response:
150+
async with session.post(
151+
self.endpoint_url, headers=operation.context.headers, **post_kwargs
152+
) as response:
145153
if response.status == HTTPStatus.OK:
146154
await response.json()
147155

148156
if response.status in self.auth_errors:
149-
raise AuthenticationError(f"Token Expired Error {operation.context.headers}")
157+
raise AuthenticationError(
158+
f"Token Expired Error {operation.context.headers}"
159+
)
150160

151161
json_response = await response.json()
152162

153163
if "errors" in json_response:
154-
raise GraphQLException("\n".join([e["message"] for e in json_response["errors"]]))
164+
raise GraphQLException(
165+
"\n".join([e["message"] for e in json_response["errors"]]),
166+
operation=operation,
167+
errors=json_response["errors"],
168+
)
155169

156170
if "data" not in json_response:
157171
raise Exception(f"Response does not contain data {json_response}")

rath/links/auth.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,15 @@ async def aexecute(
8686
token = await self.aload_token(operation)
8787
operation.context.headers["Authorization"] = f"Bearer {token}"
8888
operation.context.initial_payload["token"] = token
89-
90-
9189

9290
try:
9391
async for result in self.next.aexecute(operation):
9492
yield result
9593

9694
except AuthenticationError as e:
9795
retry = retry + 1
98-
await self.arefresh_token(operation)
96+
token = await self.arefresh_token(operation)
97+
9998
if retry > self.maximum_refresh_attempts:
10099
raise AuthenticationError("Maximum refresh attempts reached") from e
101100

rath/operation.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,17 @@ class GraphQLResult(BaseModel):
5454
class GraphQLException(Exception):
5555
"""GraphQLException is the base exception for all GraphQL errors."""
5656

57-
pass
57+
def __init__(
58+
self,
59+
message: str,
60+
operation: Optional[Operation] = None,
61+
errors: Optional[Dict[str, Any]] = None,
62+
):
63+
"""Initialize the GraphQLException with a message and optional errors."""
64+
super().__init__(message)
65+
self.message = message
66+
self.errors = errors or {}
67+
self.operation = operation
5868

5969

6070
class SubscriptionDisconnect(GraphQLException):

rath/scalars.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def validate(cls: Type["ID"], v: "IDCoercible") -> "ID":
4444
class WithId(Protocol):
4545
"A protocol for objects that have an id attribute."
4646

47-
id: ID
47+
id: "IDCoercible"
4848

4949

5050
IDCoercible = str | ID | WithId | int

0 commit comments

Comments
 (0)