Improve crash diagnostics and isolate watcher-thread failures

Main-thread unhandled exceptions now show the traceback and log path; worker-thread exceptions log without touching Qt widgets. The download watcher catches its own loop failures and reports that it stopped instead of surfacing a blank error dialog. Adds a regression test for the watcher failure path.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
TheMajesticMagician
2026-10-25 17:22:20 -06:00
co-authored by Claude Code
parent ffe95020bc
commit 47f520fb8f
3 changed files with 34 additions and 2 deletions
+11 -2
View File
@@ -5,7 +5,9 @@ from __future__ import annotations
import logging
import os
import sys
import threading
import time
import traceback
from pathlib import Path
from PyQt6.QtCore import QEventLoop, QLockFile, QRectF, Qt, QTimer
@@ -18,7 +20,7 @@ from .auth import AuthService, CredentialStore, Session, SessionExpired
from .clamav import ClamAVService
from .config import AccountCache, SettingsStore
from .context import AppContext
from .logging_setup import configure as configure_logging
from .logging_setup import configure as configure_logging, log_path
from .quarantine import QuarantineService
from .storage import Storage
from .ui import brand, theme
@@ -73,10 +75,17 @@ def _install_exception_hook() -> None:
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
logger.critical("Unhandled exception", exc_info=(exc_type, exc_value, exc_traceback))
# Qt widget calls are not safe from worker threads. Log there and
# leave the UI alone; the page's own status/toast reports the failure.
if threading.current_thread() is not threading.main_thread():
return
detail = "".join(traceback.format_exception(exc_type, exc_value, exc_traceback)).strip()
if len(detail) > 3200:
detail = "…\n" + detail[-3200:]
try:
QMessageBox.critical(
None, "BoltClam encountered an error",
f"{exc_type.__name__}: {exc_value}\n\nDetails were written to the BoltClam log.")
f"{detail}\n\nFull details: {log_path()}")
except Exception:
pass