diff --git a/electrum/gui/qt/__init__.py b/electrum/gui/qt/__init__.py index 238a7b0f8..7f6658e16 100644 --- a/electrum/gui/qt/__init__.py +++ b/electrum/gui/qt/__init__.py @@ -45,7 +45,7 @@ import PyQt5.QtCore as QtCore from electrum.i18n import _, set_language from electrum.plugin import run_hook from electrum.base_wizard import GoBack -from electrum.util import (UserCancelled, profiler, +from electrum.util import (UserCancelled, profiler, send_exception_to_crash_reporter, WalletFileException, BitcoinException, get_new_wallet_name) from electrum.wallet import Wallet, Abstract_Wallet from electrum.wallet_db import WalletDB @@ -58,6 +58,7 @@ from .network_dialog import NetworkDialog from .stylesheet_patcher import patch_qt_stylesheet from .lightning_dialog import LightningDialog from .watchtower_dialog import WatchtowerDialog +from .exception_window import Exception_Hook if TYPE_CHECKING: from electrum.daemon import Daemon @@ -296,7 +297,7 @@ class ElectrumGui(Logger): return wrapper @count_wizards_in_progress - def start_new_window(self, path, uri, *, app_is_starting=False): + def start_new_window(self, path, uri, *, app_is_starting=False) -> Optional[ElectrumWindow]: '''Raises the window for the wallet if it is open. Otherwise opens the wallet and creates a new window for it''' wallet = None @@ -398,6 +399,8 @@ class ElectrumGui(Logger): self.app.lastWindowClosed.connect(self._maybe_quit_if_no_windows_open) self.app.aboutToQuit.connect(self._cleanup_before_exit) signal.signal(signal.SIGINT, lambda *args: self.app.quit()) + # hook for crash reporter + Exception_Hook.maybe_setup(config=self.config) # first-start network-setup try: self.init_network() @@ -411,11 +414,18 @@ class ElectrumGui(Logger): # start wizard to select/create wallet self.timer.start() path = self.config.get_wallet_path(use_gui_last_wallet=True) - if not self.start_new_window(path, self.config.get('url'), app_is_starting=True): - return + try: + if not self.start_new_window(path, self.config.get('url'), app_is_starting=True): + return + except Exception as e: + self.logger.error("error loading wallet (or creating window for it)") + send_exception_to_crash_reporter(e) + # Let Qt event loop start properly so that crash reporter window can appear. + # We will shutdown when the user closes that window, via lastWindowClosed signal. # main loop + self.logger.info("starting Qt main loop") self.app.exec_() - # on some platforms the exec_ call may not return, so use clean_up() + # on some platforms the exec_ call may not return, so use _cleanup_before_exit def stop(self): self.logger.info('closing GUI') diff --git a/electrum/gui/qt/exception_window.py b/electrum/gui/qt/exception_window.py index 66903fc9f..7712eb4ca 100644 --- a/electrum/gui/qt/exception_window.py +++ b/electrum/gui/qt/exception_window.py @@ -174,12 +174,13 @@ class Exception_Hook(QObject, Logger): self._report_exception.connect(_show_window) @classmethod - def maybe_setup(cls, *, config: 'SimpleConfig', wallet: 'Abstract_Wallet') -> None: + def maybe_setup(cls, *, config: 'SimpleConfig', wallet: 'Abstract_Wallet' = None) -> None: if not config.get(BaseCrashReporter.config_key, default=True): return if not cls._INSTANCE: cls._INSTANCE = Exception_Hook(config=config) - cls._INSTANCE.wallet_types_seen.add(wallet.wallet_type) + if wallet: + cls._INSTANCE.wallet_types_seen.add(wallet.wallet_type) def handler(self, *exc_info): self.logger.error('exception caught by crash reporter', exc_info=exc_info) diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py index fe199fc9d..0868fecb9 100644 --- a/electrum/gui/qt/main_window.py +++ b/electrum/gui/qt/main_window.py @@ -185,7 +185,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): if wallet.has_lightning(): self.wallet.config.set_key('show_channels_tab', True) - self.setup_exception_hook() + Exception_Hook.maybe_setup(config=self.config, wallet=self.wallet) self.network = gui_object.daemon.network # type: Network self.fx = gui_object.daemon.fx # type: FxThread @@ -317,10 +317,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): self._update_check_thread.checked.connect(on_version_received) self._update_check_thread.start() - def setup_exception_hook(self): - Exception_Hook.maybe_setup(config=self.config, - wallet=self.wallet) - def run_coroutine_from_thread(self, coro, on_result=None): def task(): try: