Add options for displaying errors

This commit is contained in:
CPD 2025-03-19 17:24:51 +01:00
parent 0e61cd37c3
commit bb2249c574
3 changed files with 14 additions and 8 deletions

View File

@ -48,6 +48,7 @@ logging.basicConfig(
) )
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Mechanism to catch, log and display uncaught exceptions
# This is taken from: # This is taken from:
# https://timlehr.com/2018/01/python-exception-hooks-with-qt-message-box/index.html # https://timlehr.com/2018/01/python-exception-hooks-with-qt-message-box/index.html
handler = logging.StreamHandler(stream=sys.stdout) handler = logging.StreamHandler(stream=sys.stdout)
@ -59,7 +60,8 @@ def show_exception_box(log_msg):
""" """
if QtWidgets.QApplication.instance() is not None: if QtWidgets.QApplication.instance() is not None:
errorbox = QtWidgets.QMessageBox() errorbox = QtWidgets.QMessageBox()
errorbox.setText("Oops. An unexpected error occured:\n{0}".format(log_msg)) errorbox.setWindowTitle("An Unexpected Error Occurred")
errorbox.setText(log_msg)
errorbox.exec() errorbox.exec()
else: else:
log.debug("No QApplication instance available.") log.debug("No QApplication instance available.")
@ -67,8 +69,9 @@ def show_exception_box(log_msg):
class UncaughtHook(QtCore.QObject): class UncaughtHook(QtCore.QObject):
_exception_caught = QtCore.pyqtSignal(object) _exception_caught = QtCore.pyqtSignal(object)
def __init__(self, *args, **kwargs): def __init__(self, *args, show_traceback=False, **kwargs):
super(UncaughtHook, self).__init__(*args, **kwargs) super(UncaughtHook, self).__init__(*args, **kwargs)
self.show_traceback = show_traceback
# this registers the exception_hook() function as hook with the Python interpreter # this registers the exception_hook() function as hook with the Python interpreter
sys.excepthook = self.exception_hook sys.excepthook = self.exception_hook
@ -85,12 +88,14 @@ class UncaughtHook(QtCore.QObject):
sys.__excepthook__(exc_type, exc_value, exc_traceback) sys.__excepthook__(exc_type, exc_value, exc_traceback)
else: else:
exc_info = (exc_type, exc_value, exc_traceback) exc_info = (exc_type, exc_value, exc_traceback)
log_msg = '\n'.join([''.join(traceback.format_tb(exc_traceback)), log_msg = f"{exc_type.__name__}: {exc_value}\n"
'{0}: {1}'.format(exc_type.__name__, exc_value)]) if self.show_traceback:
log_msg += "\n".join(traceback.format_tb(exc_traceback))
log.critical(f"Uncaught exception:\n {log_msg}", exc_info=exc_info) log.critical(f"Uncaught exception:\n {log_msg}", exc_info=exc_info)
# trigger message box show # trigger message box show
self._exception_caught.emit(log_msg) self._exception_caught.emit(log_msg)
# create a global instance of our class to register the hook if AppConfig.MAIN_CFG.get_or("error_show_dialog", True):
qt_exception_hook = UncaughtHook() # create a global instance of our class to register the hook
qt_exception_hook = UncaughtHook(show_traceback=AppConfig.MAIN_CFG.get_or("error_stack_trace", False))

View File

@ -331,9 +331,8 @@ class MainWindow(QMainWindow):
if self.leddev is None: if self.leddev is None:
raise RuntimeError("No led control device selected") raise RuntimeError("No led control device selected")
self.idle_stop() self.idle_stop()
if not (self.vmdev_connected() and self.leddev_connected()):
raise RuntimeError(f"Can not start measurement, a device lost connection.")
raise KeyError("Exception for testing")
name = self.w_measurement_settings.get_value("name") name = self.w_measurement_settings.get_value("name")
script = self.w_measurement_settings.get_value("led_script") script = self.w_measurement_settings.get_value("led_script")
flush_after = self.w_measurement_settings.get_value("flush_after") flush_after = self.w_measurement_settings.get_value("flush_after")

View File

@ -35,4 +35,6 @@ class AppSettings(QWidget):
w_idle_dt.setMaximum(200000) w_idle_dt.setMaximum(200000)
w_idle_dt.setSingleStep(10) w_idle_dt.setSingleStep(10)
self.w_form.add_form_row("idle_update_interval_s", "Device Connection Check Interval (s)", 30, w_plot_dt, "How often to check whether the devices are still connected.\nApplies only when not in a measurement.") self.w_form.add_form_row("idle_update_interval_s", "Device Connection Check Interval (s)", 30, w_plot_dt, "How often to check whether the devices are still connected.\nApplies only when not in a measurement.")
self.w_form.add_form_row("error_show_dialog", "Show Dialog on Error", True, QCheckBox(), "Whether to show a dialog window when uncaught errors occur\nLeave this on.")
self.w_form.add_form_row("error_stack_trace", "Stacktrace in errors", False, QCheckBox(), "Whether to show the call stack in unexpected error messages")