Closed
Description
Describe the bug
$ echo 'query ($id: ID) {session(id:$id) { addresses {address}} }' | gql-cli -v --transport=websockets ws://localhost:8080/api/graphql/web-test-202201302Vr7R/websocket -V id:1 | jq
INFO:gql.transport.websockets:>>> {"type": "connection_init", "payload": {}}
INFO:gql.transport.websockets:<<< {"type":"connection_ack"}
INFO:gql.transport.websockets:>>> {"id": "1", "type": "subscribe", "payload": {"query": "query ($id: ID) {\n session(id: $id) {\n addresses {\n address\n }\n }\n}", "variables": {"id": 1}}}
INFO:gql.transport.websockets:<<< {"type":"error","payload":[{"path":["ROOT","session","id","id"],"message":"Type mismatch. The query document has a value/variable of type (ID) but the schema expectes type (ID!)","extensions":{"code":"type_mismatch"}}],"id":"1"}
Traceback (most recent call last):
File "/home/seriy/workspace/temp_email/venv/lib/python3.9/site-packages/gql/transport/websockets.py", line 292, in _parse_answer_graphqlws
raise ValueError("payload is not a dict")
ValueError: payload is not a dict
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/seriy/workspace/temp_email/venv/bin/gql-cli", line 27, in <module>
exit_code = loop.run_until_complete(main_task)
File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/home/seriy/workspace/temp_email/venv/lib/python3.9/site-packages/gql/cli.py", line 394, in main
async for result in session.subscribe(query, **execute_args):
File "/home/seriy/workspace/temp_email/venv/lib/python3.9/site-packages/gql/client.py", line 639, in subscribe
async for result in inner_generator:
File "/home/seriy/workspace/temp_email/venv/lib/python3.9/site-packages/gql/client.py", line 549, in _subscribe
async for result in inner_generator:
File "/home/seriy/workspace/temp_email/venv/lib/python3.9/site-packages/gql/transport/websockets_base.py", line 387, in subscribe
answer_type, execution_result = await listener.get()
File "/home/seriy/workspace/temp_email/venv/lib/python3.9/site-packages/gql/transport/websockets_base.py", line 56, in get
raise item
File "/home/seriy/workspace/temp_email/venv/lib/python3.9/site-packages/gql/transport/websockets_base.py", line 309, in _receive_data_loop
answer_type, answer_id, execution_result = self._parse_answer(
File "/home/seriy/workspace/temp_email/venv/lib/python3.9/site-packages/gql/transport/websockets.py", line 414, in _parse_answer
return self._parse_answer_graphqlws(json_answer)
File "/home/seriy/workspace/temp_email/venv/lib/python3.9/site-packages/gql/transport/websockets.py", line 326, in _parse_answer_graphqlws
raise TransportProtocolError(
gql.transport.exceptions.TransportProtocolError: Server did not return a GraphQL result: {'type': 'error', 'payload': [{'path': ['ROOT', 'session', 'id', 'id'], 'message': 'Type mismatch. The query document has a value/variable of type (ID) but the schema expectes type (ID!)', 'extensions': {'code': 'type_mismatch'}}], 'id': '1'}
It seems that the graphql-ws specification declares ErrorMessage.payload
as array of GraphQLError
objects, but gql
assumes that it should be just a single error object:
gql/gql/transport/websockets.py
Lines 291 to 292 in 12fc895
Relevant test / fixtures:
gql/tests/test_websocket_exceptions.py
Lines 149 to 202 in 12fc895
To Reproduce
Query graphql-ws server with gql
in such a way, so it returns {type: error, payload: ...}
packet (for example, query a field that does not exist).
Expected behavior
gql should not crash, but rather report the errors, generated by the server.
System info (please complete the following information):
- OS: Linux
- Python version: 3.9.7
- gql version: 3.0.0
- graphql-core version: ???