Error handling implemented
This commit is contained in:
@@ -52,7 +52,7 @@ class Context:
|
|||||||
logging.debug('Handling event "{}"'.format(event))
|
logging.debug('Handling event "{}"'.format(event))
|
||||||
|
|
||||||
if isinstance(event, ErrorEvent):
|
if isinstance(event, ErrorEvent):
|
||||||
self.state = ErrorState(event.exception, self.state)
|
self.state = ErrorState(event.origin, event.message, self.state)
|
||||||
elif isinstance(event, TeardownEvent):
|
elif isinstance(event, TeardownEvent):
|
||||||
self.state = TeardownState(event.target)
|
self.state = TeardownState(event.target)
|
||||||
if event.target == TeardownEvent.EXIT:
|
if event.target == TeardownEvent.EXIT:
|
||||||
@@ -92,27 +92,41 @@ class Event:
|
|||||||
|
|
||||||
class ErrorEvent(Event):
|
class ErrorEvent(Event):
|
||||||
|
|
||||||
def __init__(self, exception):
|
def __init__(self, origin, message):
|
||||||
|
|
||||||
super().__init__('Error')
|
super().__init__('Error')
|
||||||
self.exception = exception
|
self.origin = origin
|
||||||
|
self.message = message
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
||||||
return str(self.exception)
|
return self.origin + ': ' + self.message
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def exception(self):
|
def origin(self):
|
||||||
|
|
||||||
return self._exception
|
return self._origin
|
||||||
|
|
||||||
@exception.setter
|
@origin.setter
|
||||||
def exception(self, exception):
|
def origin(self, origin):
|
||||||
|
|
||||||
if not isinstance(exception, Exception):
|
if not isinstance(origin, str):
|
||||||
raise TypeError('exception must be derived from Exception')
|
raise TypeError('origin must be a string')
|
||||||
|
|
||||||
self._exception = exception
|
self._origin = origin
|
||||||
|
|
||||||
|
@property
|
||||||
|
def message(self):
|
||||||
|
|
||||||
|
return self._message
|
||||||
|
|
||||||
|
@message.setter
|
||||||
|
def message(self, message):
|
||||||
|
|
||||||
|
if not isinstance(message, str):
|
||||||
|
raise TypeError('message must be a string')
|
||||||
|
|
||||||
|
self._message = message
|
||||||
|
|
||||||
|
|
||||||
class TeardownEvent(Event):
|
class TeardownEvent(Event):
|
||||||
@@ -184,8 +198,10 @@ class State:
|
|||||||
|
|
||||||
class ErrorState(State):
|
class ErrorState(State):
|
||||||
|
|
||||||
def __init__(self, exception, old_state):
|
def __init__(self, origin, message, old_state):
|
||||||
|
|
||||||
|
self.origin = origin
|
||||||
|
self.message = message
|
||||||
self.old_state = old_state
|
self.old_state = old_state
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
@@ -193,6 +209,32 @@ class ErrorState(State):
|
|||||||
|
|
||||||
return 'ErrorState'
|
return 'ErrorState'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def origin(self):
|
||||||
|
|
||||||
|
return self._origin
|
||||||
|
|
||||||
|
@origin.setter
|
||||||
|
def origin(self, origin):
|
||||||
|
|
||||||
|
if not isinstance(origin, str):
|
||||||
|
raise TypeError('origin must be a string')
|
||||||
|
|
||||||
|
self._origin = origin
|
||||||
|
|
||||||
|
@property
|
||||||
|
def message(self):
|
||||||
|
|
||||||
|
return self._message
|
||||||
|
|
||||||
|
@message.setter
|
||||||
|
def message(self, message):
|
||||||
|
|
||||||
|
if not isinstance(message, str):
|
||||||
|
raise TypeError('message must be a string')
|
||||||
|
|
||||||
|
self._message = message
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def old_state(self):
|
def old_state(self):
|
||||||
|
|
||||||
|
|||||||
@@ -135,11 +135,17 @@ class PyQt5Gui(GuiSkeleton):
|
|||||||
|
|
||||||
def showError(self, state):
|
def showError(self, state):
|
||||||
|
|
||||||
logging.error('%s: %s', state.title, state.message)
|
logging.error('%s: %s', state.origin, state.message)
|
||||||
|
|
||||||
MessageBox(self, MessageBox.RETRY, state.title, state.message,
|
reply = QtWidgets.QMessageBox.critical(
|
||||||
lambda: self._comm.send(Workers.MASTER, GuiEvent('retry')),
|
self._gui, state.origin, 'Error: ' + state.message,
|
||||||
lambda: self._comm.send(Workers.MASTER, GuiEvent('abort')))
|
QtWidgets.QMessageBox.Retry | QtWidgets.QMessageBox.Cancel,
|
||||||
|
QtWidgets.QMessageBox.Cancel)
|
||||||
|
|
||||||
|
if reply == QtWidgets.QMessageBox.Retry:
|
||||||
|
self._comm.send(Workers.MASTER, GuiEvent('retry'))
|
||||||
|
else:
|
||||||
|
self._comm.send(Workers.MASTER, GuiEvent('abort'))
|
||||||
|
|
||||||
def showWelcome(self, state):
|
def showWelcome(self, state):
|
||||||
|
|
||||||
@@ -287,69 +293,3 @@ class PyQt5MainWindow(QtWidgets.QMainWindow):
|
|||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
|
|
||||||
self._handle_key(event)
|
self._handle_key(event)
|
||||||
|
|
||||||
|
|
||||||
class MessageBox(QtWidgets.QWidget):
|
|
||||||
|
|
||||||
QUESTION = 1
|
|
||||||
RETRY = 2
|
|
||||||
INFORMATION = 3
|
|
||||||
|
|
||||||
def __init__(self, parent, type, title, message, *handles):
|
|
||||||
|
|
||||||
super().__init__(parent)
|
|
||||||
|
|
||||||
if type == MessageBox.QUESTION:
|
|
||||||
self.question(title, message, *handles)
|
|
||||||
elif type == MessageBox.RETRY:
|
|
||||||
self.retry(title, message, *handles)
|
|
||||||
else:
|
|
||||||
raise ValueError('Unknown type specified')
|
|
||||||
|
|
||||||
def question(self, title, message, *handles):
|
|
||||||
|
|
||||||
lbl_title = QtWidgets.QLabel(title)
|
|
||||||
lbl_title.setObjectName('title')
|
|
||||||
|
|
||||||
lbl_message = QtWidgets.QLabel(message)
|
|
||||||
lbl_message.setObjectName('message')
|
|
||||||
|
|
||||||
btn_yes = QtWidgets.QPushButton('Yes')
|
|
||||||
btn_yes.clicked.connect(handles[0])
|
|
||||||
|
|
||||||
btn_no = QtWidgets.QPushButton('No')
|
|
||||||
btn_no.clicked.connect(handles[1])
|
|
||||||
|
|
||||||
lay_buttons = QtWidgets.QHBoxLayout()
|
|
||||||
lay_buttons.addWidget(btn_yes)
|
|
||||||
lay_buttons.addWidget(btn_no)
|
|
||||||
|
|
||||||
layout = QtWidgets.QVBoxLayout()
|
|
||||||
layout.addWidget(lbl_title)
|
|
||||||
layout.addWidget(lbl_message)
|
|
||||||
layout.addLayout(lay_buttons)
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|
||||||
def retry(self, title, message, *handles):
|
|
||||||
|
|
||||||
lbl_title = QtWidgets.QLabel(title)
|
|
||||||
lbl_title.setObjectName('title')
|
|
||||||
|
|
||||||
lbl_message = QtWidgets.QLabel(message)
|
|
||||||
lbl_message.setObjectName('message')
|
|
||||||
|
|
||||||
btn_retry = QtWidgets.QPushButton('Retry')
|
|
||||||
btn_retry.clicked.connect(handles[0])
|
|
||||||
|
|
||||||
btn_cancel = QtWidgets.QPushButton('Cancel')
|
|
||||||
btn_cancel.clicked.connect(handles[1])
|
|
||||||
|
|
||||||
lay_buttons = QtWidgets.QHBoxLayout()
|
|
||||||
lay_buttons.addWidget(btn_retry)
|
|
||||||
lay_buttons.addWidget(btn_cancel)
|
|
||||||
|
|
||||||
layout = QtWidgets.QVBoxLayout()
|
|
||||||
layout.addWidget(lbl_title)
|
|
||||||
layout.addWidget(lbl_message)
|
|
||||||
layout.addLayout(lay_buttons)
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class CameraProcess(mp.Process):
|
|||||||
if cap.run():
|
if cap.run():
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._comm.send(Workers.MASTER, ErrorEvent(e))
|
self._comm.send(Workers.MASTER, ErrorEvent('Camera', str(e)))
|
||||||
|
|
||||||
|
|
||||||
class WorkerProcess(mp.Process):
|
class WorkerProcess(mp.Process):
|
||||||
@@ -77,7 +77,7 @@ class WorkerProcess(mp.Process):
|
|||||||
if Worker(self.cfg, self.comm).run():
|
if Worker(self.cfg, self.comm).run():
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._comm.send(Workers.MASTER, ErrorEvent(e))
|
self._comm.send(Workers.MASTER, ErrorEvent('Worker', str(e)))
|
||||||
|
|
||||||
|
|
||||||
class GuiProcess(mp.Process):
|
class GuiProcess(mp.Process):
|
||||||
|
|||||||
Reference in New Issue
Block a user