Skip to content

Commit 982f0d8

Browse files
authored
fix: Fix Sentry Change Tracking response handling (#5573)
1 parent 61db807 commit 982f0d8

File tree

5 files changed

+246
-163
lines changed

5 files changed

+246
-163
lines changed

api/integrations/sentry/change_tracking.py

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import json
2-
import logging
32
from typing import Any
43

54
import requests
5+
import structlog
66
from django.core.serializers.json import DjangoJSONEncoder
77

88
from audit.models import AuditLog
@@ -11,7 +11,7 @@
1111
from features.models import FeatureState
1212
from integrations.common.wrapper import AbstractBaseEventIntegrationWrapper
1313

14-
logger = logging.getLogger(__name__)
14+
logger = structlog.get_logger("sentry_change_tracking")
1515

1616

1717
class SentryChangeTracking(AbstractBaseEventIntegrationWrapper):
@@ -59,17 +59,19 @@ def generate_event_data(audit_log_record: AuditLog) -> dict[str, Any]:
5959
"id": getattr(audit_log_record.author, "email", "app@flagsmith.com"),
6060
"type": "email",
6161
},
62+
"change_id": str(feature_state.pk),
6263
}
6364

64-
if action == "updated":
65-
inner_payload["change_id"] = str(feature_state.pk)
66-
6765
return inner_payload
6866

6967
def _track_event(self, event: dict[str, Any]) -> None:
7068
action = event["action"]
7169
feature_name = event["flag"]
72-
logger.debug("Sending '%s' (%s) to Sentry...", feature_name, action)
70+
71+
log = logger.bind(
72+
sentry_action=action,
73+
feature_name=feature_name,
74+
)
7375

7476
payload = {
7577
"data": [event],
@@ -82,21 +84,33 @@ def _track_event(self, event: dict[str, Any]) -> None:
8284
"X-Sentry-Signature": sign_payload(json_payload, self.secret),
8385
}
8486

85-
response = requests.post(
87+
log.debug(
88+
"sending",
8689
url=self.webhook_url,
8790
headers=headers,
88-
data=json_payload,
91+
payload=payload,
8992
)
9093

9194
try:
92-
response.raise_for_status()
95+
response = requests.post(
96+
url=self.webhook_url,
97+
headers=headers,
98+
data=json_payload,
99+
)
100+
response.raise_for_status() # NOTE: This is for future-proofing, as Sentry won't respond 4xx.
93101
except requests.exceptions.RequestException as error:
94-
# TODO: Should we retry, or ultimately notify the admin of a persisting issue?
95-
logger.error(
96-
"Error sending '%s' (%s) to Sentry: %s",
97-
feature_name,
98-
action,
99-
repr(error),
102+
log.warning(
103+
"request-failure",
104+
error=error,
100105
)
101-
else:
102-
logger.debug("Sent '%s' (%s) to Sentry", feature_name, action)
106+
return
107+
108+
if not response.text: # This is fragile and undocumented. ¯\_(ツ)_/¯
109+
log.info("success")
110+
return
111+
112+
log.warning(
113+
"integration-error",
114+
sentry_response_status=response.status_code,
115+
sentry_response_body=response.text,
116+
)

api/poetry.lock

Lines changed: 19 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ types-python-dateutil = "^2.9.0.20241206"
236236
types-pytz = "^2025.1.0.20250204"
237237
ruff = "^0.9.7"
238238
flagsmith-common = { version = "*", extras = ["test-tools"] }
239+
pytest-responses = "^0.5.1"
239240

240241
[build-system]
241242
requires = ["poetry>=2.0.0"]

0 commit comments

Comments
 (0)