Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions src/sentry/utils/sdk_crashes/event_stripper.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,32 @@ def strip_event_data(
and the method only keeps SDK frames and system library frames.
"""

frames = get_path(event_data, "exception", "values", -1, "stacktrace", "frames")
if not frames:
last_exception = get_path(
event_data,
"exception",
"values",
-1,
)
if not last_exception:
return {}

# The SDK crash detector only detects crashes based on the last exception value.
# Therefore, if the last exception doesn't contain a stacktrace something is off and
# we can drop the whole event.
last_exception_frames = get_path(last_exception, "stacktrace", "frames")
if not last_exception_frames:
return {}

event_data_copy = dict(event_data)

# We strip the frames first because applying the allowlist removes fields that are needed
# for deciding wether to keep a frame or not.
stripped_frames = _strip_frames(frames, sdk_crash_detector)
stripped_frames = _strip_frames(last_exception_frames, sdk_crash_detector)
last_exception["stacktrace"]["frames"] = stripped_frames
Comment thread
philipphofmann marked this conversation as resolved.

event_data_copy = dict(event_data)
event_data_copy["exception"]["values"][0]["stacktrace"]["frames"] = stripped_frames
# We only keep the last exception. We need to adopt the allowlist and stripping event data logic
# to support multiple exceptions.
event_data_copy["exception"]["values"] = [last_exception]

stripped_event_data = _strip_event_data_with_allowlist(event_data_copy, EVENT_DATA_ALLOWLIST)

Expand Down
74 changes: 74 additions & 0 deletions tests/sentry/utils/sdk_crashes/test_event_stripper.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,3 +452,77 @@ def test_strip_event_without_frames_returns_empty_dict(store_and_strip_event) ->
stripped_event_data = store_and_strip_event(data=event_data)

assert stripped_event_data == {}


@django_db_all
@pytest.mark.snuba
def test_strip_event_with_multiple_exceptions_only_keep_last_one(store_and_strip_event) -> None:
event_data = get_crash_event()

exception_values = list(get_path(event_data, "exception", "values"))

crash_exception = dict(exception_values[0])
set_path(crash_exception, "type", value="SIGPIPE")
set_path(crash_exception, "value", value="Broken pipe")

exception_values.append(crash_exception)

set_path(event_data, "exception", "values", value=exception_values)

stripped_event_data = store_and_strip_event(data=event_data)

assert len(get_path(stripped_event_data, "exception", "values")) == 1

exception = get_path(stripped_event_data, "exception", "values", 0)
assert exception["type"] == "SIGPIPE"
assert "value" not in exception


@django_db_all
@pytest.mark.snuba
def test_strip_event_with_multiple_exceptions_last_without_frames_discard_event(
store_and_strip_event,
) -> None:
event_data = get_crash_event()

exception_values = list(get_path(event_data, "exception", "values"))

crash_exception = dict(exception_values[0])
set_path(crash_exception, "type", value="SIGPIPE")
set_path(crash_exception, "value", value="Broken pipe")
set_path(crash_exception, "stacktrace", value=None)
exception_values.append(crash_exception)

set_path(event_data, "exception", "values", value=exception_values)

stripped_event_data = store_and_strip_event(data=event_data)

assert stripped_event_data == {}


@django_db_all
@pytest.mark.snuba
def test_strip_event_with_multiple_exceptions_first_without_frames_keeps_last_exception(
store_and_strip_event,
) -> None:
event_data = get_crash_event()

exception_values = list(get_path(event_data, "exception", "values"))

crash_exception = dict(exception_values[0])
set_path(crash_exception, "type", value="SIGPIPE")
set_path(crash_exception, "value", value="Broken pipe")
exception_values.append(crash_exception)

# Remove the stacktrace from the first exception.
exception_values[0]["stacktrace"] = None

set_path(event_data, "exception", "values", value=exception_values)

stripped_event_data = store_and_strip_event(data=event_data)

assert len(get_path(stripped_event_data, "exception", "values")) == 1

exception = get_path(stripped_event_data, "exception", "values", 0)
assert exception["type"] == "SIGPIPE"
assert "value" not in exception
Loading