Skip to content

Fix KeyError when errors is not iterable #359

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions gql/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from .utilities import build_client_schema
from .utilities import parse_result as parse_result_fn
from .utilities import serialize_variable_values
from .utils import str_first_element

"""
Load the appropriate instance of the Literal type
Expand Down Expand Up @@ -152,7 +153,8 @@ def _build_schema_from_introspection(self, execution_result: ExecutionResult):
if execution_result.errors:
raise TransportQueryError(
(
f"Error while fetching schema: {execution_result.errors[0]!s}\n"
"Error while fetching schema: "
f"{str_first_element(execution_result.errors)}\n"
"If you don't need the schema, you can try with: "
'"fetch_schema_from_transport=False"'
),
Expand Down Expand Up @@ -858,7 +860,7 @@ def execute(
# Raise an error if an error is returned in the ExecutionResult object
if result.errors:
raise TransportQueryError(
str(result.errors[0]),
str_first_element(result.errors),
errors=result.errors,
data=result.data,
extensions=result.extensions,
Expand Down Expand Up @@ -1066,7 +1068,7 @@ async def subscribe(
# Raise an error if an error is returned in the ExecutionResult object
if result.errors:
raise TransportQueryError(
str(result.errors[0]),
str_first_element(result.errors),
errors=result.errors,
data=result.data,
extensions=result.extensions,
Expand Down Expand Up @@ -1229,7 +1231,7 @@ async def execute(
# Raise an error if an error is returned in the ExecutionResult object
if result.errors:
raise TransportQueryError(
str(result.errors[0]),
str_first_element(result.errors),
errors=result.errors,
data=result.data,
extensions=result.extensions,
Expand Down
11 changes: 10 additions & 1 deletion gql/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Utilities to manipulate several python objects."""

from typing import Any, Dict, Tuple, Type
from typing import Any, Dict, List, Tuple, Type


# From this response in Stackoverflow
Expand Down Expand Up @@ -47,3 +47,12 @@ def recurse_extract(path, obj):
nulled_variables = recurse_extract("variables", variables)

return nulled_variables, files


def str_first_element(errors: List) -> str:
try:
first_error = errors[0]
except (KeyError, TypeError):
first_error = errors

return str(first_error)
13 changes: 8 additions & 5 deletions tests/test_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,18 +199,21 @@ async def handler(request):
assert "500, message='Internal Server Error'" in str(exc_info.value)


query1_server_error_answer = '{"errors": ["Error 1", "Error 2"]}'
transport_query_error_responses = [
'{"errors": ["Error 1", "Error 2"]}',
'{"errors": {"error_1": "Something"}}',
'{"errors": 5}',
]


@pytest.mark.asyncio
async def test_aiohttp_error_code(event_loop, aiohttp_server):
@pytest.mark.parametrize("query_error", transport_query_error_responses)
async def test_aiohttp_error_code(event_loop, aiohttp_server, query_error):
from aiohttp import web
from gql.transport.aiohttp import AIOHTTPTransport

async def handler(request):
return web.Response(
text=query1_server_error_answer, content_type="application/json"
)
return web.Response(text=query_error, content_type="application/json")

app = web.Application()
app.router.add_route("POST", "/", handler)
Expand Down