From 928369bbf0682de2b91daeac015ab27d1728b16a Mon Sep 17 00:00:00 2001 From: Erica Pisani Date: Mon, 5 Oct 2026 11:27:16 -0400 Subject: [PATCH 1/2] ref(strawberry)!: Drop `send_default_pii` support in request data The request event processor now reads only the `data_collection` options for the GraphQL document and variables, and no longer falls back to `send_default_pii`. It also no longer removes `request.data` when neither option is set, so a body attached by the web framework integration is left untouched (as the attaching of the body is controlled by the `http_bodies` property in the `data_collection` settings) Fixes PY-2843 Fixes #7614 --- sentry_sdk/integrations/strawberry.py | 59 +++----- .../strawberry/test_strawberry.py | 138 ++++-------------- 2 files changed, 45 insertions(+), 152 deletions(-) diff --git a/sentry_sdk/integrations/strawberry.py b/sentry_sdk/integrations/strawberry.py index da3e2f0b63..e227da2adc 100644 --- a/sentry_sdk/integrations/strawberry.py +++ b/sentry_sdk/integrations/strawberry.py @@ -366,50 +366,29 @@ def _make_request_event_processor( def inner(event: "Event", hint: "dict[str, Any]") -> "Event": client_options = sentry_sdk.get_client().options with capture_internal_exceptions(): - if has_data_collection_enabled(client_options): - request_data = event.setdefault("request", {}) - if client_options["data_collection"]["graphql"]["document"]: - request_data["api_target"] = "graphql" - - if not request_data.get("data"): - execution_context_data: "dict[str, Any]" = ( - {"query": execution_context.query} - if client_options["data_collection"]["graphql"]["document"] - else {} - ) - - if ( - client_options["data_collection"]["graphql"]["variables"] - and execution_context.variables - ): - execution_context_data["variables"] = ( - execution_context.variables - ) - - if execution_context.operation_name: - execution_context_data["operationName"] = ( - execution_context.operation_name - ) - - request_data["data"] = execution_context_data - elif should_send_default_pii(): - request_data = event.setdefault("request", {}) + request_data = event.setdefault("request", {}) + if client_options["data_collection"]["graphql"]["document"]: request_data["api_target"] = "graphql" - if not request_data.get("data"): - data: "dict[str, Any]" = {"query": execution_context.query} - if execution_context.variables: - data["variables"] = execution_context.variables - if execution_context.operation_name: - data["operationName"] = execution_context.operation_name + if not request_data.get("data"): + execution_context_data: "dict[str, Any]" = ( + {"query": execution_context.query} + if client_options["data_collection"]["graphql"]["document"] + else {} + ) - request_data["data"] = data + if ( + client_options["data_collection"]["graphql"]["variables"] + and execution_context.variables + ): + execution_context_data["variables"] = execution_context.variables - else: - try: - del event["request"]["data"] - except (KeyError, TypeError): - pass + if execution_context.operation_name: + execution_context_data["operationName"] = ( + execution_context.operation_name + ) + + request_data["data"] = execution_context_data return event diff --git a/tests/integrations/strawberry/test_strawberry.py b/tests/integrations/strawberry/test_strawberry.py index ccd7dfb0d7..55ea8aaad3 100644 --- a/tests/integrations/strawberry/test_strawberry.py +++ b/tests/integrations/strawberry/test_strawberry.py @@ -171,64 +171,6 @@ def test_replace_existing_sentry_sync_extension(sentry_init): assert SentrySyncExtension in schema.extensions -@parameterize_strawberry_test -def test_capture_request_if_available_and_send_pii_is_on( - request, - sentry_init, - capture_events, - client_factory, - async_execution, - framework_integrations, -): - sentry_init( - send_default_pii=True, - integrations=[ - StrawberryIntegration(async_execution=async_execution), - ] - + framework_integrations, - ) - events = capture_events() - - schema = strawberry.Schema(Query) - - client_factory = request.getfixturevalue(client_factory) - client = client_factory(schema) - - query = "query ErrorQuery { error }" - client.post("/graphql", json={"query": query, "operationName": "ErrorQuery"}) - - assert len(events) == 1 - - (error_event,) = events - - assert len(error_event["exception"]["values"]) == 2 - assert error_event["exception"]["values"][0]["mechanism"]["type"] == "chained" - assert error_event["exception"]["values"][-1]["mechanism"]["type"] == "strawberry" - assert error_event["request"]["api_target"] == "graphql" - assert error_event["request"]["data"] == { - "query": query, - "operationName": "ErrorQuery", - } - assert error_event["contexts"]["response"] == { - "data": { - "data": None, - "errors": [ - { - "message": "division by zero", - "locations": [{"line": 1, "column": 20}], - "path": ["error"], - } - ], - } - } - assert len(error_event["breadcrumbs"]["values"]) == 1 - assert error_event["breadcrumbs"]["values"][0]["category"] == "graphql.operation" - assert error_event["breadcrumbs"]["values"][0]["data"] == { - "operation_name": "ErrorQuery", - "operation_type": "query", - } - - @parameterize_strawberry_test def test_do_not_capture_request_if_send_pii_is_off( request, @@ -239,6 +181,10 @@ def test_do_not_capture_request_if_send_pii_is_off( framework_integrations, ): sentry_init( + data_collection={ + "graphql": {"document": False, "variables": False}, + "http_bodies": [], + }, integrations=[ StrawberryIntegration(async_execution=async_execution), ] @@ -261,7 +207,8 @@ def test_do_not_capture_request_if_send_pii_is_off( assert len(error_event["exception"]["values"]) == 2 assert error_event["exception"]["values"][0]["mechanism"]["type"] == "chained" assert error_event["exception"]["values"][-1]["mechanism"]["type"] == "strawberry" - assert "data" not in error_event["request"] + assert error_event["request"]["data"] == {"operationName": "ErrorQuery"} + assert "response" not in error_event["contexts"] assert len(error_event["breadcrumbs"]["values"]) == 1 @@ -274,32 +221,18 @@ def test_do_not_capture_request_if_send_pii_is_off( @parameterize_strawberry_test @pytest.mark.parametrize( - "data_collection,send_default_pii,expect_api_target", + "data_collection,expect_api_target", [ pytest.param( {"graphql": {"document": True}}, - None, True, id="document_on_sets_api_target", ), pytest.param( {"graphql": {"document": False}}, - None, False, id="document_off_omits_api_target", ), - pytest.param( - {"graphql": {"document": False}}, - True, - False, - id="data_collection_takes_precedence_over_send_default_pii_on", - ), - pytest.param( - {"graphql": {"document": True}}, - False, - True, - id="data_collection_takes_precedence_over_send_default_pii_off", - ), ], ) def test_event_processor_data_collection( @@ -310,7 +243,6 @@ def test_event_processor_data_collection( async_execution, framework_integrations, data_collection, - send_default_pii, expect_api_target, ): init_kwargs = { @@ -318,8 +250,6 @@ def test_event_processor_data_collection( + framework_integrations, "data_collection": data_collection, } - if send_default_pii is not None: - init_kwargs["send_default_pii"] = send_default_pii sentry_init(**init_kwargs) events = capture_events() @@ -894,6 +824,16 @@ def test_graphql_span_data_collection( @parameterize_strawberry_test +@pytest.mark.parametrize( + "data_collection", + [ + pytest.param(None, id="data_collection_default"), + pytest.param( + {"graphql": {"document": True, "variables": True}}, + id="data_collection_graphql_on", + ), + ], +) def test_handle_none_query_gracefully( request, sentry_init, @@ -901,41 +841,15 @@ def test_handle_none_query_gracefully( client_factory, async_execution, framework_integrations, + data_collection, ): - sentry_init( - integrations=[ - StrawberryIntegration(async_execution=async_execution), - ] - + framework_integrations, - ) - events = capture_events() - - schema = strawberry.Schema(Query) - - client_factory = request.getfixturevalue(client_factory) - client = client_factory(schema) - - client.post("/graphql", json={}) - - assert len(events) == 0, "expected no events to be sent to Sentry" - - -@parameterize_strawberry_test -def test_handle_none_query_gracefully_with_data_collection( - request, - sentry_init, - capture_events, - client_factory, - async_execution, - framework_integrations, -): - sentry_init( - integrations=[ - StrawberryIntegration(async_execution=async_execution), - ] + init_kwargs = { + "integrations": [StrawberryIntegration(async_execution=async_execution)] + framework_integrations, - data_collection={"graphql": {"document": True, "variables": True}}, - ) + } + if data_collection is not None: + init_kwargs["data_collection"] = data_collection + sentry_init(**init_kwargs) events = capture_events() schema = strawberry.Schema(Query) @@ -949,7 +863,7 @@ def test_handle_none_query_gracefully_with_data_collection( @parameterize_strawberry_test -def test_span_origin( +def test_span_origin_for_gql_mutations_and_related_ops( request, sentry_init, capture_events, @@ -998,7 +912,7 @@ def test_span_origin( @parameterize_strawberry_test -def test_span_origin2( +def test_span_origin_for_gql_query_ops( request, sentry_init, capture_events, From 89dd11449d7b044f6fd5dc425cefe2d235b061a9 Mon Sep 17 00:00:00 2001 From: Erica Pisani Date: Mon, 5 Oct 2026 11:33:25 -0400 Subject: [PATCH 2/2] more test cleanups --- .../strawberry/test_strawberry.py | 69 +++---------------- 1 file changed, 10 insertions(+), 59 deletions(-) diff --git a/tests/integrations/strawberry/test_strawberry.py b/tests/integrations/strawberry/test_strawberry.py index 55ea8aaad3..2c35d9818f 100644 --- a/tests/integrations/strawberry/test_strawberry.py +++ b/tests/integrations/strawberry/test_strawberry.py @@ -172,7 +172,7 @@ def test_replace_existing_sentry_sync_extension(sentry_init): @parameterize_strawberry_test -def test_do_not_capture_request_if_send_pii_is_off( +def test_do_not_capture_request_if_data_collection_settings_are_off( request, sentry_init, capture_events, @@ -475,10 +475,6 @@ def test_breadcrumb_no_operation_name( @parameterize_strawberry_test -@pytest.mark.parametrize( - "send_default_pii", - [True, False], -) def test_capture_segment_on_error( request, sentry_init, @@ -487,10 +483,9 @@ def test_capture_segment_on_error( client_factory, async_execution, framework_integrations, - send_default_pii, ): sentry_init( - send_default_pii=send_default_pii, + data_collection={}, integrations=[ StrawberryIntegration(async_execution=async_execution), ] @@ -526,10 +521,7 @@ def test_capture_segment_on_error( assert query_span["attributes"]["graphql.operation.type"] == "query" assert query_span["attributes"]["graphql.operation.name"] == "ErrorQuery" - if send_default_pii is True: - assert query_span["attributes"]["graphql.document"] == query - else: - assert "graphql.document" not in query_span["attributes"] + assert query_span["attributes"]["graphql.document"] == query assert parse_span["attributes"]["sentry.op"] == OP.GRAPHQL_PARSE assert parse_span["name"] == "parsing" @@ -545,10 +537,6 @@ def test_capture_segment_on_error( @parameterize_strawberry_test -@pytest.mark.parametrize( - "send_default_pii", - [True, False], -) def test_capture_segment_on_success( request, sentry_init, @@ -557,7 +545,6 @@ def test_capture_segment_on_success( client_factory, async_execution, framework_integrations, - send_default_pii, ): sentry_init( integrations=[ @@ -565,7 +552,7 @@ def test_capture_segment_on_success( ] + framework_integrations, traces_sample_rate=1, - send_default_pii=send_default_pii, + data_collection={}, ) items = capture_items("span") @@ -593,10 +580,7 @@ def test_capture_segment_on_success( assert query_span["attributes"]["graphql.operation.type"] == "query" assert query_span["attributes"]["graphql.operation.name"] == "GreetingQuery" - if send_default_pii is True: - assert query_span["attributes"]["graphql.document"] == query - else: - assert "graphql.document" not in query_span["attributes"] + assert query_span["attributes"]["graphql.document"] == query assert parse_span["attributes"]["sentry.op"] == OP.GRAPHQL_PARSE assert parse_span["name"] == "parsing" @@ -612,10 +596,6 @@ def test_capture_segment_on_success( @parameterize_strawberry_test -@pytest.mark.parametrize( - "send_default_pii", - [True, False], -) def test_segment_no_operation_name( request, sentry_init, @@ -624,7 +604,6 @@ def test_segment_no_operation_name( client_factory, async_execution, framework_integrations, - send_default_pii, ): sentry_init( integrations=[ @@ -632,7 +611,7 @@ def test_segment_no_operation_name( ] + framework_integrations, traces_sample_rate=1, - send_default_pii=send_default_pii, + data_collection={}, ) items = capture_items("span") @@ -659,10 +638,7 @@ def test_segment_no_operation_name( assert query_span["attributes"]["graphql.operation.type"] == "query" assert "graphql.operation.name" not in query_span["attributes"] - if send_default_pii is True: - assert query_span["attributes"]["graphql.document"] == query - else: - assert "graphql.document" not in query_span["attributes"] + assert query_span["attributes"]["graphql.document"] == query assert parse_span["attributes"]["sentry.op"] == OP.GRAPHQL_PARSE assert parse_span["name"] == "parsing" @@ -678,10 +654,6 @@ def test_segment_no_operation_name( @parameterize_strawberry_test -@pytest.mark.parametrize( - "send_default_pii", - [True, False], -) def test_segment_mutation( request, sentry_init, @@ -690,7 +662,6 @@ def test_segment_mutation( client_factory, async_execution, framework_integrations, - send_default_pii, ): sentry_init( integrations=[ @@ -698,7 +669,7 @@ def test_segment_mutation( ] + framework_integrations, traces_sample_rate=1, - send_default_pii=send_default_pii, + data_collection={}, ) items = capture_items("span") @@ -726,10 +697,7 @@ def test_segment_mutation( assert mutation_span["attributes"]["graphql.operation.type"] == "mutation" assert "graphql.operation.name" not in mutation_span["attributes"] - if send_default_pii is True: - assert mutation_span["attributes"]["graphql.document"] == query - else: - assert "graphql.document" not in mutation_span["attributes"] + assert mutation_span["attributes"]["graphql.document"] == query assert parse_span["attributes"]["sentry.op"] == OP.GRAPHQL_PARSE assert parse_span["name"] == "parsing" @@ -746,32 +714,18 @@ def test_segment_mutation( @parameterize_strawberry_test @pytest.mark.parametrize( - "data_collection,send_default_pii,expect_document", + "data_collection,expect_document", [ pytest.param( {"graphql": {"document": True}}, - None, True, id="document_on_sets_graphql_document", ), pytest.param( {"graphql": {"document": False}}, - None, False, id="document_off_omits_graphql_document", ), - pytest.param( - {"graphql": {"document": False}}, - True, - False, - id="data_collection_takes_precedence_over_send_default_pii_on", - ), - pytest.param( - {"graphql": {"document": True}}, - False, - True, - id="data_collection_takes_precedence_over_send_default_pii_off", - ), ], ) def test_graphql_span_data_collection( @@ -783,7 +737,6 @@ def test_graphql_span_data_collection( async_execution, framework_integrations, data_collection, - send_default_pii, expect_document, ): init_kwargs = { @@ -792,8 +745,6 @@ def test_graphql_span_data_collection( "traces_sample_rate": 1, "data_collection": data_collection, } - if send_default_pii is not None: - init_kwargs["send_default_pii"] = send_default_pii sentry_init(**init_kwargs)