Skip to content

Commit 3ed1872

Browse files
authored
fix(replays): Drop and log click events with negative node-ids (#66993)
Negative node-ids can't be inserted into our database because of type issues. Let's drop them for now. We'll also log them so we can figure out if they're important (and possibly debug an SDK issue).
1 parent f6cb475 commit 3ed1872

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

src/sentry/replays/usecases/ingest/dom_index.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ def create_click_event(
231231
replay_id: str,
232232
is_dead: bool,
233233
is_rage: bool,
234+
project_id: int,
234235
) -> ReplayActionsEventPayloadClick | None:
235236
node = payload.get("data", {}).get("node")
236237
if node is None:
@@ -242,7 +243,7 @@ def create_click_event(
242243
# before truncating the list.
243244
classes = _parse_classes(attributes.get("class", ""))
244245

245-
return {
246+
event: ReplayActionsEventPayloadClick = {
246247
"node_id": node["id"],
247248
"tag": node["tagName"][:32],
248249
"id": attributes.get("id", "")[:64],
@@ -262,6 +263,18 @@ def create_click_event(
262263
),
263264
}
264265

266+
# This is unsupported and will cause errors on insert! Let's drop these bad clicks
267+
# and logs them to bigquery to see if we can figure out where they're coming from.
268+
if event["node_id"] < 0:
269+
# Log to "slow_click" because its the only bigquery sink
270+
logger.info(
271+
"sentry.replays.slow_click",
272+
extra={"event_type": "negative-click-node-id", "project_id": project_id, "data": event},
273+
)
274+
return None
275+
276+
return event
277+
265278

266279
def _parse_classes(classes: str) -> list[str]:
267280
return list(filter(lambda n: n != "", classes.split(" ")))[:10]
@@ -383,7 +396,9 @@ def _handle_breadcrumb(
383396
is_rage = (
384397
payload["data"].get("clickCount", 0) or payload["data"].get("clickcount", 0)
385398
) >= 5
386-
click = create_click_event(payload, replay_id, is_dead=True, is_rage=is_rage)
399+
click = create_click_event(
400+
payload, replay_id, is_dead=True, is_rage=is_rage, project_id=project_id
401+
)
387402
if click is not None:
388403
if is_rage:
389404
metrics.incr("replay.rage_click_detected")
@@ -417,7 +432,9 @@ def _handle_breadcrumb(
417432
log["dom_tree"] = log.pop("message")
418433
logger.info("sentry.replays.slow_click", extra=log)
419434
elif category == "ui.click":
420-
click = create_click_event(payload, replay_id, is_dead=False, is_rage=False)
435+
click = create_click_event(
436+
payload, replay_id, is_dead=False, is_rage=False, project_id=project_id
437+
)
421438
if click is not None:
422439
return click
423440
return None

tests/sentry/replays/unit/test_ingest_dom_index.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,3 +1098,43 @@ def test_log_canvas_size():
10981098

10991099
# No events.
11001100
log_canvas_size(1, 1, "a", [])
1101+
1102+
1103+
def test_emit_click_negative_node_id():
1104+
"""Test "get_user_actions" function."""
1105+
events = [
1106+
{
1107+
"type": 5,
1108+
"timestamp": 1674298825,
1109+
"data": {
1110+
"tag": "breadcrumb",
1111+
"payload": {
1112+
"timestamp": 1674298825.403,
1113+
"type": "default",
1114+
"category": "ui.click",
1115+
"message": "div#hello.hello.world",
1116+
"data": {
1117+
"nodeId": 1,
1118+
"node": {
1119+
"id": -1,
1120+
"tagName": "div",
1121+
"attributes": {
1122+
"id": "hello",
1123+
"class": "hello world",
1124+
"aria-label": "test",
1125+
"role": "button",
1126+
"alt": "1",
1127+
"data-testid": "2",
1128+
"title": "3",
1129+
"data-sentry-component": "SignUpForm",
1130+
},
1131+
"textContent": "Hello, world!",
1132+
},
1133+
},
1134+
},
1135+
},
1136+
}
1137+
]
1138+
1139+
user_actions = get_user_actions(1, uuid.uuid4().hex, events, None)
1140+
assert len(user_actions) == 0

0 commit comments

Comments
 (0)