Skip to content

Commit 8adbf74

Browse files
authored
ref(grouping): Small enhancements refactors (#90101)
This is a series of small refactors to enhancements code, extracted from upcoming PRs in order to make them easier to review. No behavior changes. - Break the base64 helper functions up into more steps. - Pull the rust exception data into its own variable before passing it to the rust enhancer. - Remove `Enhancements.as_dict` and the `EnhancementsDict` type. These used to be used in the `/grouping-enhancements` endpoint, but it was removed 4 years ago in #24854. - Clean up enhancement tests (mostly adding/organizing helper functions and fixtures).
1 parent 286a948 commit 8adbf74

File tree

2 files changed

+285
-346
lines changed

2 files changed

+285
-346
lines changed

src/sentry/grouping/enhancer/__init__.py

+17-30
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from collections import Counter
88
from collections.abc import Sequence
99
from functools import cached_property
10-
from typing import Any, Literal, NotRequired, TypedDict
10+
from typing import Any, Literal
1111

1212
import msgpack
1313
import sentry_sdk
@@ -16,15 +16,14 @@
1616
from sentry_ophio.enhancers import Component as RustFrame
1717
from sentry_ophio.enhancers import Enhancements as RustEnhancements
1818

19-
from sentry import projectoptions
2019
from sentry.grouping.component import FrameGroupingComponent, StacktraceGroupingComponent
2120
from sentry.stacktraces.functions import set_in_app
2221
from sentry.utils.safe import get_path, set_path
2322

2423
from .exceptions import InvalidEnhancerConfig
2524
from .matchers import create_match_frame
2625
from .parser import parse_enhancements
27-
from .rules import EnhancementRule, EnhancementRuleDict
26+
from .rules import EnhancementRule
2827

2928
logger = logging.getLogger(__name__)
3029

@@ -134,13 +133,6 @@ def keep_profiling_rules(config: str) -> str:
134133
return "\n".join(filtered_rules)
135134

136135

137-
class EnhancementsDict(TypedDict):
138-
id: str | None
139-
bases: list[str]
140-
latest: bool
141-
rules: NotRequired[list[EnhancementRuleDict]]
142-
143-
144136
class Enhancements:
145137
# NOTE: You must add a version to ``VERSIONS`` any time attributes are added
146138
# to this class, s.t. no enhancements lacking these attributes are loaded
@@ -178,9 +170,10 @@ def apply_category_and_updated_in_app_to_frames(
178170
"""
179171
# TODO: Fix this type to list[MatchFrame] once it's fixed in ophio
180172
match_frames: list[Any] = [create_match_frame(frame, platform) for frame in frames]
173+
rust_exception_data = make_rust_exception_data(exception_data)
181174

182175
category_and_in_app_results = self.rust_enhancements.apply_modifications_to_frames(
183-
match_frames, make_rust_exception_data(exception_data)
176+
match_frames, rust_exception_data
184177
)
185178

186179
for frame, (category, in_app) in zip(frames, category_and_in_app_results):
@@ -209,13 +202,14 @@ def assemble_stacktrace_component(
209202
match_frames: list[Any] = [create_match_frame(frame, platform) for frame in frames]
210203

211204
rust_frames = [RustFrame(contributes=c.contributes) for c in frame_components]
205+
rust_exception_data = make_rust_exception_data(exception_data)
212206

213207
# Modify the rust frames by applying +group/-group rules and getting hints for both those
214208
# changes and the `in_app` changes applied by earlier in the ingestion process by
215209
# `apply_category_and_updated_in_app_to_frames`. Also, get `hint` and `contributes` values
216210
# for the overall stacktrace (returned in `rust_results`).
217211
rust_stacktrace_results = self.rust_enhancements.assemble_stacktrace_component(
218-
match_frames, make_rust_exception_data(exception_data), rust_frames
212+
match_frames, rust_exception_data, rust_frames
219213
)
220214

221215
# Tally the number of each type of frame in the stacktrace. Later on, this will allow us to
@@ -292,19 +286,6 @@ def assemble_stacktrace_component(
292286

293287
return stacktrace_component
294288

295-
def as_dict(self, with_rules: bool = False) -> EnhancementsDict:
296-
rv: EnhancementsDict = {
297-
"id": self.id,
298-
"bases": self.bases,
299-
"latest": projectoptions.lookup_well_known_key(
300-
"sentry:grouping_enhancements_base"
301-
).get_default(epoch=projectoptions.LATEST_EPOCH)
302-
== self.id,
303-
}
304-
if with_rules:
305-
rv["rules"] = [x.as_dict() for x in self.rules]
306-
return rv
307-
308289
def _to_config_structure(self) -> list[Any]:
309290
# TODO: Can we switch this to a tuple so we can type it more exactly?
310291
return [
@@ -318,7 +299,9 @@ def base64_string(self) -> str:
318299
"""A base64 string representation of the enhancements object"""
319300
pickled = msgpack.dumps(self._to_config_structure())
320301
compressed_pickle = zstandard.compress(pickled)
321-
return base64.urlsafe_b64encode(compressed_pickle).decode("ascii").strip("=")
302+
base64_bytes = base64.urlsafe_b64encode(compressed_pickle).strip(b"=")
303+
base64_str = base64_bytes.decode("ascii")
304+
return base64_str
322305

323306
@classmethod
324307
def _from_config_structure(
@@ -339,9 +322,12 @@ def _from_config_structure(
339322
@classmethod
340323
def from_base64_string(cls, base64_string: str | bytes) -> Enhancements:
341324
"""Convert a base64 string into an `Enhancements` object"""
342-
if isinstance(base64_string, str):
343-
base64_string = base64_string.encode("ascii", "ignore")
344-
padded_bytes = base64_string + b"=" * (4 - (len(base64_string) % 4))
325+
bytes_str = (
326+
base64_string.encode("ascii", "ignore")
327+
if isinstance(base64_string, str)
328+
else base64_string
329+
)
330+
padded_bytes = bytes_str + b"=" * (4 - (len(bytes_str) % 4))
345331
try:
346332
compressed_pickle = base64.urlsafe_b64decode(padded_bytes)
347333

@@ -351,8 +337,9 @@ def from_base64_string(cls, base64_string: str | bytes) -> Enhancements:
351337
pickled = zlib.decompress(compressed_pickle)
352338

353339
rust_enhancements = get_rust_enhancements("config_structure", pickled)
340+
config_structure = msgpack.loads(pickled, raw=False)
354341

355-
return cls._from_config_structure(msgpack.loads(pickled, raw=False), rust_enhancements)
342+
return cls._from_config_structure(config_structure, rust_enhancements)
356343
except (LookupError, AttributeError, TypeError, ValueError) as e:
357344
raise ValueError("invalid stack trace rule config: %s" % e)
358345

0 commit comments

Comments
 (0)