I'm having trouble getting my head around exceptions in QThreads. Consider this example :
from PyQt5 import QtCore, QtGui, QtWidgets
import time
class Worker(QtCore.QObject):
@QtCore.pyqtSlot()
def do_stuff(self):
print("Hello from worker")
time.sleep(2)
raise Exception("worker crashed")
class Gui(QtWidgets.QWidget):
def __init__(self):
super(Gui, self).__init__()
self.worker = Worker()
self.thread = QtCore.QThread()
self.worker.moveToThread(self.thread)
self.thread.start()
button = QtWidgets.QPushButton(text="do stuff in worker")
button.clicked.connect(self.worker.do_stuff)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(button)
self.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = Gui()
app.exec_()
Gui creates a Worker object, moves it to a QThread and starts it. The worker object can receive signals and process them in its own thread, as not to block the Gui.
However, if an exception is raised inside the worker, the whole program crashes with (on windows) a STATUS_STACK_BUFFER_OVERRUN error (0xC0000409). It seems to be the expected behavior as of PyQt version 5.5
In this situation, the fix that seems to be recommended is to catch exceptions in the worker, maybe emit a signal back to the Gui with some exception info and let it handle it. This solution doesn't seem ideal, as it would require to wrap every method in the worker with some try/except machinery.
Is there any other solution ? How to properly handle crashes in QThreads ?
User contributions licensed under CC BY-SA 3.0