Skip to content

Commit c857d91

Browse files
authored
fix(txnames): Prevent recursion error (#59421)
Prevent recursion errors in transaction clustering. This only happens for very deep trees, which do not make good transaction names or span descriptions in the first place. Fixes [SENTRY-170T](https://sentry.sentry.io/issues/4559413640/)
1 parent 5f93df7 commit c857d91

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

src/sentry/ingest/transaction_clusterer/tree.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ class Merged:
6868
#: Separator by which we build the tree
6969
SEP = "/"
7070

71+
#: Maximum tree depth. URLs with more than 200 segments do not seem useful,
72+
#: and we occasionally run into `RecursionError`s.
73+
MAX_DEPTH = 200
74+
7175

7276
logger = logging.getLogger(__name__)
7377

@@ -80,7 +84,7 @@ def __init__(self, *, merge_threshold: int) -> None:
8084

8185
def add_input(self, strings: Iterable[str]) -> None:
8286
for string in strings:
83-
parts = string.split(SEP)
87+
parts = string.split(SEP, maxsplit=MAX_DEPTH)
8488
node = self._tree
8589
for part in parts:
8690
node = node.setdefault(part, Node())

tests/sentry/ingest/test_transaction_clusterer.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ def test_single_leaf():
6363
assert clusterer.get_rules() == ["/a/*/**"]
6464

6565

66+
def test_deep_tree():
67+
clusterer = TreeClusterer(merge_threshold=1)
68+
transaction_names = [
69+
1001 * "/.",
70+
]
71+
clusterer.add_input(transaction_names)
72+
73+
# Does not throw an exception:
74+
clusterer.get_rules()
75+
76+
6677
@mock.patch("sentry.ingest.transaction_clusterer.datasource.redis.MAX_SET_SIZE", 5)
6778
def test_collection():
6879
org = Organization(pk=666)

0 commit comments

Comments
 (0)