fix(message): rate-limit "Could not parse" warnings per NAME#1566
Merged
edenhaus merged 3 commits intoMay 7, 2026
Merged
Conversation
When a firmware version pushes messages whose on-wire format the lib does not yet support, every push triggers a `Could not parse <NAME>` WARNING via `_handle_error_or_analyse`. In one observed case a mower's spontaneous `getMapTrace` pushes produced 217 520 identical entries in 3 days (~70k/day, ~50/min during mowing), bloating the parent process' log file and any downstream sink (HA recorder DB, Loki, etc.). The first few warnings are useful — they let an operator notice that something is wrong. Beyond that, identical repeats add no information and only make the rest of the log harder to read. This adds a per-NAME counter and a threshold (default 3): the first 3 parse failures for a given message NAME are still logged at WARNING, followed by a single notice that further entries will be downgraded to DEBUG. After that, all subsequent parse failures for that NAME log at DEBUG. Counters are isolated per NAME, so a NEW message class hitting a parse error still surfaces normally. The 3 existing emission sites (`_handle_error_or_analyse` exception path, `_handle_error_or_analyse` ERROR-state path, `MessageBodyData` exception path) all route through the new helper. Behaviour for non-throttled flows (success, ANALYSE) is unchanged. Tests: - `test_warn_once_throttles_repeated_parse_failures` — calls `Message.handle()` `THRESHOLD + 2` times on a class whose `_handle` always raises, asserts THRESHOLD + 1 WARNINGs (incl. the "switching to DEBUG" notice) followed by 2 DEBUGs. - `test_warn_once_isolated_per_message_name` — burns through the threshold for one NAME, verifies a sibling NAME still WARNs on its first parse failure. - Full suite: 699/699 pass. Refs: DeebotUniverse#1376
This was referenced Apr 29, 2026
edenhaus
requested changes
Apr 29, 2026
…log assertions Address review feedback on DeebotUniverse#1566: - Remove the file-level explanatory comment block above the threshold - Drop the "Restart Home Assistant" line — the lib does not know its host - Replace per-NAME counter cleanup with a pytest fixture that wipes the whole dict before and after each test - Compare ``caplog.records`` against the full expected level/message list in order (the previous count-only assertion would have passed with WARNING/DEBUG entries interleaved out of order)
edenhaus
requested changes
May 7, 2026
edenhaus
left a comment
Member
There was a problem hiding this comment.
Please make sure CI is passing
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #1566 +/- ##
==========================================
+ Coverage 94.92% 94.99% +0.07%
==========================================
Files 156 158 +2
Lines 6105 6197 +92
Branches 350 352 +2
==========================================
+ Hits 5795 5887 +92
Misses 248 248
Partials 62 62 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a firmware version pushes messages whose on-wire format the lib does not yet support, every push triggers a
Could not parse <NAME>WARNING via_handle_error_or_analyse. In one observed case a mower's spontaneousgetMapTracepushes produced 217 520 identical entries in 3 days (~70k/day, ~50/min during mowing), bloating the parent process' log file and any downstream sink (HA recorder DB, Loki, etc.).The first few warnings are useful — they let an operator notice that something is wrong. Beyond that, identical repeats add no information and only make the rest of the log harder to read.
Change
Per-NAME counter with a default threshold of 3:
Counters are isolated per NAME, so a new message class hitting a parse error still surfaces normally even if another NAME has been silenced.
The 3 existing emission sites all route through the new
_log_parse_failurehelper:_handle_error_or_analyseexception branch (line 68)_handle_error_or_analyseERROR-state branch (line 84)MessageBodyData.__handle_body_dataexception branch (line 259)Behaviour for non-throttled flows (
SUCCESS,ANALYSE) is unchanged.Refs
getMapTracemower-skip — together they should fully eliminate the user's observed log storm)Test plan
test_warn_once_throttles_repeated_parse_failures— callsMessage.handle()THRESHOLD + 2 times on a class whose_handlealways raises, asserts THRESHOLD + 1 WARNINGs (incl. the "switching to DEBUG" notice) followed by 2 DEBUGstest_warn_once_isolated_per_message_name— burns through the threshold for one NAME, verifies a sibling NAME still WARNs on its first parse failureNotes for review
Messageclass attribute if that fits the project style better.