From 7bda83998ef19ca74d3bb90a3950a602809a5db3 Mon Sep 17 00:00:00 2001 From: Vlad Doloman Date: Fri, 26 Jun 2026 18:27:52 +0300 Subject: [PATCH] fix: handle bare {"stage":"name"} loading payload; harden watcher against parser errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stage-transition payload {"state":"loading","payload":{"stage":"mmproj_model"}} lacks the stages/current/value keys — accessing them raised KeyError which crashed the LogWatcher task, freezing the UI at the last good state indefinitely. - log_parser: skip loading payloads missing stages/current/value (next message has the full payload within milliseconds) - log_watcher: wrap on_line calls in try/except so any future parser error keeps the tail loop alive instead of killing the task Co-Authored-By: Claude Sonnet 4.6 --- log_parser.py | 4 ++++ log_watcher.py | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/log_parser.py b/log_parser.py index 484024a..99cc075 100644 --- a/log_parser.py +++ b/log_parser.py @@ -200,6 +200,10 @@ class LogParser: payload = data.get("payload") if s == "loading" and payload: + # Some transition messages only carry {"stage":"name"} with no + # progress info — skip them; the next message has the full payload. + if not all(k in payload for k in ("stages", "current", "value")): + return None loading = LoadingInfo( stages=payload["stages"], current=payload["current"], diff --git a/log_watcher.py b/log_watcher.py index fdf6282..c56931a 100644 --- a/log_watcher.py +++ b/log_watcher.py @@ -56,7 +56,10 @@ class LogWatcher: while True: line = f.readline() if line: - await self._on_line(line) + try: + await self._on_line(line) + except Exception: + pass # keep tailing even if a line causes a parser error else: await asyncio.sleep(self.POLL_INTERVAL) except OSError: @@ -96,7 +99,10 @@ class LogWatcher: line = f.readline() if line: pos = f.tell() - await self._on_line(line) + try: + await self._on_line(line) + except Exception: + pass # keep tailing even if a line causes a parser error else: break