Add an uncaught exception handler.

This commit is contained in:
Dan Albert 2021-08-29 16:09:47 -07:00
parent 60a5ee42fe
commit cd15de6d42
2 changed files with 46 additions and 1 deletions

View File

@ -0,0 +1,42 @@
# From https://timlehr.com/python-exception-hooks-with-qt-message-box/
import logging
import sys
import traceback
from PySide2.QtCore import Signal, QObject
from PySide2.QtWidgets import QMessageBox, QApplication
class UncaughtExceptionHandler(QObject):
_exception_caught = Signal(str, str)
def __init__(self, parent: QObject):
super().__init__(parent)
sys.excepthook = self.exception_hook
# Use a signal so that the message box always comes from the main thread.
self._exception_caught.connect(self.show_exception_box)
def exception_hook(self, exc_type, exc_value, exc_traceback):
if issubclass(exc_type, KeyboardInterrupt):
# Ignore keyboard interrupt to support console applications.
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
logging.exception(
"Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)
)
self._exception_caught.emit(
str(exc_value),
"".join(traceback.format_exception(exc_type, exc_value, exc_traceback)),
)
def show_exception_box(self, message: str, exception: str) -> None:
if QApplication.instance() is not None:
QMessageBox().critical(
self.parent(),
"An unexpected error occurred",
"\n".join([message, "", exception]),
QMessageBox.Ok,
)
else:
logging.critical("No QApplication instance available.")

View File

@ -24,6 +24,7 @@ from qt_ui import liberation_install
from qt_ui.dialogs import Dialog from qt_ui.dialogs import Dialog
from qt_ui.models import GameModel from qt_ui.models import GameModel
from qt_ui.uiconstants import URLS from qt_ui.uiconstants import URLS
from qt_ui.uncaughtexceptionhandler import UncaughtExceptionHandler
from qt_ui.widgets.QTopPanel import QTopPanel from qt_ui.widgets.QTopPanel import QTopPanel
from qt_ui.widgets.ato import QAirTaskingOrderPanel from qt_ui.widgets.ato import QAirTaskingOrderPanel
from qt_ui.widgets.map.QLiberationMap import QLiberationMap from qt_ui.widgets.map.QLiberationMap import QLiberationMap
@ -42,7 +43,9 @@ from qt_ui.windows.logs.QLogsWindow import QLogsWindow
class QLiberationWindow(QMainWindow): class QLiberationWindow(QMainWindow):
def __init__(self, game: Optional[Game]) -> None: def __init__(self, game: Optional[Game]) -> None:
super(QLiberationWindow, self).__init__() super().__init__()
self._uncaught_exception_handler = UncaughtExceptionHandler(self)
self.game = game self.game = game
self.game_model = GameModel(game) self.game_model = GameModel(game)