Collect repeated send failures in the stashed-errors view instead of flooding the log#2936
Merged
Merged
Conversation
A device that stops responding (left the network, powered off) turns every send into an error line: the ember driver rejects with 'Delivery failed' and no error code, so filterError logs each attempt at error level. With an automation still commanding the device this fills the log with one identical line per ~5 seconds - tens of thousands of lines per day for a single dead bulb, drowning every other message, while not even showing when the problem started. The adapter already has the right tool for exactly this situation: the stashed-errors collection in the states controller (used for the min/max value warnings and unknown models) - first occurrence is logged, repeats only bump a counter with first/last-seen timestamps, visible in the errors view of the admin tab and in info.lasterror. This change routes the error-level branches of filterError (no error code, unknown code, E_ERROR, malformed) through that collection when the caller provides a stash key; without a key the behaviour is unchanged. The send path in publishFromState passes 'send:<device>' as key, and clears it again on the first successful send to that device (new unstashError, which also recalculates hasData so the errors button disappears once everything is resolved) - a later outage starts with a fresh error line again. The first logged line carries a short hint that repeats are counted, not logged. The info/warn/debug severities of the error code table are deliberately untouched - those are already rate-appropriate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
The problem
A device that stops responding (left the network, powered off) turns every send into an error line: the ember driver rejects with
Delivery failed for '<nwk>'and no error code, sofilterErrortakes the no-code branch and logs every attempt at error level. With an automation still commanding the device (a scene, a bridge, a script), the send queue drains one failed attempt per ~5 seconds — that is one identical log line per ~5 seconds, around the clock:Observed live: ~18,000 identical lines per day for a single dead bulb. Every other message drowns in between, and the flood does not even show when the problem started.
The fix — reuse the existing stashed-errors collection
The adapter already has exactly the right tool: the stashed-errors collection in the states controller (today used for the min/max value warnings and unknown models) — first occurrence is logged, repeats only bump a counter with first/last-seen timestamps, and the errors view in the admin tab plus
info.lasterrorshow the live state.This PR routes the error-level branches of
filterError(no error code, unknown code, E_ERROR, malformed) through that collection when the caller provides a stash key; without a key the behaviour is byte-for-byte unchanged. The send path inpublishFromStatepassessend:<device>as key and clears it again on the first successful send to that device — so a later outage starts with a fresh error line instead of counting silently. Clearing recalculateshasData, so the errors button disappears once everything is resolved. The first logged line carries a short hint that repeats are counted, not logged.The info/warn/debug severities of the error-code table (9999 → info, 233 MAC NO ACK → debug, 205/134 → warn) are deliberately untouched — those are already rate-appropriate.
Resulting behaviour for a dead device
info.lasterroris updated per occurrenceVerification
main.jsfilterError/logFilteredError+ the realStatesController): one line then silence, counter/timestamps/info.lasterror, reset-on-success, fresh logging after reset,hasDatarecalculation with and without remaining entries, no-key behaviour unchanged (two calls = two lines), coded paths info/warn/debug unchanged and not collected, unknown-code path collected, existing min/max stash behaviour unchangednode --checkon all touched files, ESLint clean,npm testgreenNote: the
filterErrorcall site inpublishFromStateoverlaps with a line #2934 touches (the devLabel model parameter). Whichever lands second, I will rebase immediately.🤖 Generated with Claude Code