Skip to content

Commit

Permalink
Added GraphQL error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Anton-Shutik committed Dec 13, 2024
1 parent 97d5e9b commit 82e9116
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
2 changes: 2 additions & 0 deletions shopify_client/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class GraphQLError(Exception):
pass
9 changes: 8 additions & 1 deletion shopify_client/graphql.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import requests

from .exceptions import GraphQLError

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -56,7 +58,12 @@ def __query(
"operationName": operation_name,
},
)
return self.client.parse_response(response)
parsed_response = self.client.parse_response(response)
if "errors" in parsed_response:
logger.warning(f"GraphQL errors: {parsed_response['errors']}")
if "data" not in parsed_response:
raise GraphQLError(f"GraphQL errors: {parsed_response['errors']}")
return parsed_response
except requests.exceptions.HTTPError as e:
logger.warning(f"Failed to execute GraphQL query: {repr(e)}")
raise e
Expand Down
41 changes: 41 additions & 0 deletions tests/test_graphql.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from unittest.mock import call, mock_open, patch
import requests
import pytest
from shopify_client.exceptions import GraphQLError
from shopify_client.graphql import GraphQL
from tests.conftest import CopyingMock

Expand Down Expand Up @@ -159,3 +160,43 @@ def test_paginated_query_requires_has_next_page(graphql, mock_client):
def test_paginated_query_requires_end_cursor(graphql, mock_client):
with pytest.raises(AssertionError):
list(graphql(query="query { pageInfo { hasNextPage } }", paginate=True))


def test_graphql_query_handles_empty_data_with_errors_only(graphql, mock_client):
mock_client.post.return_value = {"errors": [{"message": "Another error occurred"}]}
with pytest.raises(GraphQLError, match='[{"message": "Another error occurred"}]'):
graphql(query="query { key }")


def test_graphql_query_reraises_http_error(graphql, mock_client):
mock_client.post.side_effect = requests.exceptions.HTTPError("HTTP Error")
with pytest.raises(requests.exceptions.HTTPError):
graphql(query="query { key }")


def test_graphql_query_reraises_json_error(graphql, mock_client):
mock_client.post.side_effect = json.JSONDecodeError("JSON Decode Error", "", 0)
with pytest.raises(json.JSONDecodeError):
graphql(query="query { key }")


def test_graphql_query_handles_data_with_errors(graphql, mock_client):
mock_client.post.return_value = {
"data": {"key": "value"},
"errors": [{"message": "Some error occurred"}],
}

# Mock the logger from the client
with patch("shopify_client.graphql.logger") as mock_logger:
response = graphql(query="query { key }")

# Check that the response contains the data
assert response == {
"data": {"key": "value"},
"errors": [{"message": "Some error occurred"}],
}

# Verify that the logger was called with the expected message
mock_logger.warning.assert_called_once_with(
"GraphQL errors: [{'message': 'Some error occurred'}]"
)

0 comments on commit 82e9116

Please sign in to comment.