From 63aee31c9cc7544a4b39aff60f4c6ba43b94223f Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 9 Jan 2026 09:58:19 +0100 Subject: [PATCH 1/2] fix(gql): Revert signature change of patched gql.Client.execute --- sentry_sdk/integrations/gql.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sentry_sdk/integrations/gql.py b/sentry_sdk/integrations/gql.py index 083ceaf517..c19a518f46 100644 --- a/sentry_sdk/integrations/gql.py +++ b/sentry_sdk/integrations/gql.py @@ -95,18 +95,23 @@ def _request_info_from_transport( def _patch_execute() -> None: real_execute = gql.Client.execute + # Maintain signature for backwards compatibility. + # gql.Client.execute() accepts a positional-only "request" + # parameter with version 4.0.0. @ensure_integration_enabled(GQLIntegration, real_execute) def sentry_patched_execute( self: "gql.Client", - document_or_request: "DocumentNode", + document: "DocumentNode", *args: "Any", **kwargs: "Any", ) -> "Any": scope = sentry_sdk.get_isolation_scope() - scope.add_event_processor(_make_gql_event_processor(self, document_or_request)) + # document is a gql.GraphQLRequest with gql v4.0.0. + scope.add_event_processor(_make_gql_event_processor(self, document)) try: - return real_execute(self, document_or_request, *args, **kwargs) + # document is a gql.GraphQLRequest with gql v4.0.0. + return real_execute(self, document, *args, **kwargs) except TransportQueryError as e: event, hint = event_from_exception( e, From 8fdafd19d9b2abf71215d86d907eff48e725f032 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 9 Jan 2026 10:31:14 +0100 Subject: [PATCH 2/2] add tests --- tests/integrations/gql/test_gql.py | 54 +++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/tests/integrations/gql/test_gql.py b/tests/integrations/gql/test_gql.py index 147f7a06a8..2785c63e2c 100644 --- a/tests/integrations/gql/test_gql.py +++ b/tests/integrations/gql/test_gql.py @@ -3,9 +3,13 @@ import responses from gql import gql from gql import Client +from gql import __version__ from gql.transport.exceptions import TransportQueryError from gql.transport.requests import RequestsHTTPTransport from sentry_sdk.integrations.gql import GQLIntegration +from sentry_sdk.utils import parse_version + +GQL_VERSION = parse_version(__version__) @responses.activate @@ -32,7 +36,36 @@ def _execute_mock_query(response_json): return client.execute(query) -def _make_erroneous_query(capture_events): +@responses.activate +def _execute_mock_query_with_keyword_document(response_json): + url = "http://example.com/graphql" + query_string = """ + query Example { + example + } + """ + + # Mock the GraphQL server response + responses.add( + method=responses.POST, + url=url, + json=response_json, + status=200, + ) + + transport = RequestsHTTPTransport(url=url) + client = Client(transport=transport) + query = gql(query_string) + + return client.execute(document=query) + + +_execute_query_funcs = [_execute_mock_query] +if GQL_VERSION < (4,): + _execute_query_funcs.append(_execute_mock_query_with_keyword_document) + + +def _make_erroneous_query(capture_events, execute_query): """ Make an erroneous GraphQL query, and assert that the error was reraised, that exactly one event was recorded, and that the exception recorded was a @@ -42,7 +75,7 @@ def _make_erroneous_query(capture_events): response_json = {"errors": ["something bad happened"]} with pytest.raises(TransportQueryError): - _execute_mock_query(response_json) + execute_query(response_json) assert len(events) == 1, ( "the sdk captured %d events, but 1 event was expected" % len(events) @@ -67,7 +100,8 @@ def test_gql_init(sentry_init): sentry_init(integrations=[GQLIntegration()]) -def test_real_gql_request_no_error(sentry_init, capture_events): +@pytest.mark.parametrize("execute_query", _execute_query_funcs) +def test_real_gql_request_no_error(sentry_init, capture_events, execute_query): """ Integration test verifying that the GQLIntegration works as expected with successful query. """ @@ -77,7 +111,7 @@ def test_real_gql_request_no_error(sentry_init, capture_events): response_data = {"example": "This is the example"} response_json = {"data": response_data} - result = _execute_mock_query(response_json) + result = execute_query(response_json) assert result == response_data, ( "client.execute returned a different value from what it received from the server" @@ -87,27 +121,31 @@ def test_real_gql_request_no_error(sentry_init, capture_events): ) -def test_real_gql_request_with_error_no_pii(sentry_init, capture_events): +@pytest.mark.parametrize("execute_query", _execute_query_funcs) +def test_real_gql_request_with_error_no_pii(sentry_init, capture_events, execute_query): """ Integration test verifying that the GQLIntegration works as expected with query resulting in a GraphQL error, and that PII is not sent. """ sentry_init(integrations=[GQLIntegration()]) - event = _make_erroneous_query(capture_events) + event = _make_erroneous_query(capture_events, execute_query) assert "data" not in event["request"] assert "response" not in event["contexts"] -def test_real_gql_request_with_error_with_pii(sentry_init, capture_events): +@pytest.mark.parametrize("execute_query", _execute_query_funcs) +def test_real_gql_request_with_error_with_pii( + sentry_init, capture_events, execute_query +): """ Integration test verifying that the GQLIntegration works as expected with query resulting in a GraphQL error, and that PII is not sent. """ sentry_init(integrations=[GQLIntegration()], send_default_pii=True) - event = _make_erroneous_query(capture_events) + event = _make_erroneous_query(capture_events, execute_query) assert "data" in event["request"] assert "response" in event["contexts"]