Source code for PartSeg.common_backend.except_hook
import logging
import sys
import sentry_sdk
from qtpy.QtCore import QCoreApplication, QThread
from qtpy.QtWidgets import QMessageBox
from superqt import ensure_main_thread
from PartSeg import state_store
from PartSegCore.segmentation.algorithm_base import SegmentationLimitException
from PartSegImage import TiffFileException
[docs]
def my_excepthook(type_, value, trace_back):
"""
Custom excepthook.
Close application on :py:class:`KeyboardInterrupt`.
If :py:data:`PartSeg.state_store.always_report` is set then just sent report using sentry.
otherwise show dialog with information about error and ask user
if he wants to send report using :py:func:`show_error`.
"""
# log the exception here
if state_store.show_error_dialog and not isinstance(value, KeyboardInterrupt):
if state_store.auto_report or state_store.always_report:
with sentry_sdk.push_scope() as scope:
scope.set_tag("auto_report", "true")
scope.set_tag("main_thread", QCoreApplication.instance().thread() == QThread.currentThread())
sentry_sdk.capture_exception(value)
if state_store.always_report:
return
try:
show_error(value)
except ImportError:
sys.__excepthook__(type_, value, trace_back)
elif isinstance(value, KeyboardInterrupt):
logging.warning("KeyboardInterrupt close")
sys.exit(1)
else:
# then call the default handler
sys.__excepthook__(type_, value, trace_back)
[docs]
@ensure_main_thread
def show_error(error=None):
"""
For :py:class:`SegmentationLimitException` and :py:class:`TiffFileException`
show dialog with information about problem.
For other exceptions show :py:class:`ErrorDialog` dialog
with information about error that allow to report it.
:param error: exception to show
"""
if error is None:
return
from PartSeg.common_gui.error_report import ErrorDialog, QMessageFromException
if isinstance(error, TiffFileException):
QMessageFromException.critical(
None,
"Tiff file error",
f"During read file there is an error: {', '.join(str(x) for x in error.args)}",
exception=error,
)
return
if isinstance(error, SegmentationLimitException):
QMessageFromException.critical(
None,
"Segmentation limitations",
f"During segmentation process algorithm meet limitations: {', '.join(str(x) for x in error.args)}",
exception=error,
)
return
dial = ErrorDialog(error, "Exception during program run")
dial.exec_()
[docs]
@ensure_main_thread
def show_warning(header=None, text=None, exception=None):
"""
Show warning :py:class:`PyQt5.QtWidgets.QMessageBox`
This function is to ensure creation warning dialog in main thread.
"""
if exception is not None:
from PartSeg.common_gui.error_report import QMessageFromException
message = QMessageFromException(QMessageBox.Icon.Warning, header, text, exception=exception)
else:
message = QMessageBox(QMessageBox.Icon.Warning, header, text, QMessageBox.StandardButton.Ok)
message.exec_()