refactor(events): raise on malformed stream id instead of lex fallback

stream_id_compare's lex-fallback branch was a footgun: a malformed id
that sorts lex-greater than a real one would pin live-tail dedup
forever, dropping every subsequent legitimate event silently. Both
current callers in application/api/events/routes.py pre-validate
inputs against _STREAM_ID_RE before calling, so changing the function
to raise ValueError is a no-op on the happy path and turns the future-
caller footgun into a loud failure.
This commit is contained in:
Alex
2026-05-12 19:09:48 +01:00
parent aa91117fbf
commit 746bcbc5f9
2 changed files with 17 additions and 15 deletions

View File

@@ -35,19 +35,16 @@ def stream_id_compare(a: str, b: str) -> int:
Stream ids are ``ms-seq`` strings; comparing as strings would be wrong
once ``ms`` straddles digit-count boundaries. We parse and compare
as ``(int, int)`` tuples.
Raises ``ValueError`` on malformed input. Callers must pre-validate
against ``_STREAM_ID_RE`` (or equivalent) — a lex fallback here let
a malformed id compare lex-greater than a real one and silently pin
dedup forever.
"""
a_ms, _, a_seq = a.partition("-")
b_ms, _, b_seq = b.partition("-")
try:
a_tuple = (int(a_ms), int(a_seq) if a_seq else 0)
b_tuple = (int(b_ms), int(b_seq) if b_seq else 0)
except ValueError:
# Malformed id — fall back to lex compare so we at least don't crash.
if a < b:
return -1
if a > b:
return 1
return 0
a_tuple = (int(a_ms), int(a_seq) if a_seq else 0)
b_tuple = (int(b_ms), int(b_seq) if b_seq else 0)
if a_tuple < b_tuple:
return -1
if a_tuple > b_tuple:

View File

@@ -67,11 +67,16 @@ class TestStreamIdCompare:
def test_missing_seq_treated_as_zero(self):
assert stream_id_compare("1234", "1234-0") == 0
def test_malformed_both_sides_falls_back_to_lex(self):
# Pure lex compare on garbage — important: this must not raise.
assert stream_id_compare("foo", "bar") == 1
assert stream_id_compare("foo", "foo") == 0
assert stream_id_compare("aaa", "zzz") == -1
def test_malformed_input_raises(self):
# Callers must pre-validate; the function refuses to silently
# lex-compare garbage because a malformed id that sorts
# lex-greater would pin dedup forever.
with pytest.raises(ValueError):
stream_id_compare("foo", "bar")
with pytest.raises(ValueError):
stream_id_compare("123-0", "foo")
with pytest.raises(ValueError):
stream_id_compare("foo", "123-0")
# ── _format_sse ─────────────────────────────────────────────────────────