What
Multiple users see random red error toasts (bottom-right) in the SixBack WebUI. They often appear during normal polling even when nothing meaningful is wrong, then disappear. Workaround is a full page reload or clicking "Refresh Status".
Reported by @fred_feuerstein in the FHEM forum thread: "Hier und da kommen als Einblendung rechts unten in rot Fehlermeldungen (diverse). Meist muss man mal entweder die komplette Seite aktualisieren oder oben auf Refresh Status gehen."
Why this happens
The toast helper in web-src/index.html:770-776 writes to a single shared #toast div. The only rate-limit is clearTimeout(window._toastT) — a new toast simply overwrites the previous. No dedup, no queue, no per-class suppression for transient/expected errors.
Five most-likely sources of user-visible red toasts:
loadStatus polled every 10s (web-src/index.html:3938). Any fetch /api/status blip — TLS reuse churn, mid-OTA, ESP busy with migrate worker — toasts as 'Status: '+e.message at :853.
pollNowPlaying 30s/speaker (:2053, :2068). When the SCMUDC cache is cold AND the Bose live-fetch times out (speaker mid-reboot, settling), the inner try swallows but the surrounding 10s api('/api/status') tick still toasts.
loadSpotifyTriggers 5s poll (:3950) — errors route through api() and surface to the user.
- Verify-retry loops after push-all (
:1658-1683, :2231-2250) — each /hardware-presets retry that catches a 502 (speaker mid-reboot) raises.
kickPoll after D&D (:2027-2031): three staggered pollNowPlaying calls at 0/0.8/2.5s, each can independently toast on the first run after a slow Bose response.
Proposed fixes
:770-776 (toast helper): add dedup — keep lastToastMsg + lastToastAt, skip same message within ~8s.
:853 (status polling): suppress the Status: toast entirely; replace with an inline indicator on #status-meta ("offline / retrying").
:1149 (speaker list) + :2055-2082 (pollNowPlaying): use a warn class (or stay silent) for transient HTTP failures; reserve error for user-initiated actions.
:2027-2031 (kickPoll): wrap inner calls so they never surface; they are optimistic background probes.
Acceptance
- Idle WebUI on a healthy stack produces 0 red toasts for 5+ minutes
- A real error (e.g. speaker permanently unreachable) still surfaces once, not repeatedly
- Dedup window visible in the dev console
What
Multiple users see random red error toasts (bottom-right) in the SixBack WebUI. They often appear during normal polling even when nothing meaningful is wrong, then disappear. Workaround is a full page reload or clicking "Refresh Status".
Reported by @fred_feuerstein in the FHEM forum thread: "Hier und da kommen als Einblendung rechts unten in rot Fehlermeldungen (diverse). Meist muss man mal entweder die komplette Seite aktualisieren oder oben auf Refresh Status gehen."
Why this happens
The toast helper in
web-src/index.html:770-776writes to a single shared#toastdiv. The only rate-limit isclearTimeout(window._toastT)— a new toast simply overwrites the previous. No dedup, no queue, no per-class suppression for transient/expected errors.Five most-likely sources of user-visible red toasts:
loadStatuspolled every 10s (web-src/index.html:3938). Anyfetch /api/statusblip — TLS reuse churn, mid-OTA, ESP busy with migrate worker — toasts as'Status: '+e.messageat:853.pollNowPlaying30s/speaker (:2053, :2068). When the SCMUDC cache is cold AND the Bose live-fetch times out (speaker mid-reboot, settling), the inner try swallows but the surrounding 10sapi('/api/status')tick still toasts.loadSpotifyTriggers5s poll (:3950) — errors route throughapi()and surface to the user.:1658-1683, :2231-2250) — each/hardware-presetsretry that catches a 502 (speaker mid-reboot) raises.kickPollafter D&D (:2027-2031): three staggeredpollNowPlayingcalls at 0/0.8/2.5s, each can independently toast on the first run after a slow Bose response.Proposed fixes
:770-776(toast helper): add dedup — keeplastToastMsg+lastToastAt, skip same message within ~8s.:853(status polling): suppress theStatus:toast entirely; replace with an inline indicator on#status-meta("offline / retrying").:1149(speaker list) +:2055-2082(pollNowPlaying): use awarnclass (or stay silent) for transient HTTP failures; reserveerrorfor user-initiated actions.:2027-2031(kickPoll): wrap inner calls so they never surface; they are optimistic background probes.Acceptance