You first need a catch-all exception clause in your thread, otherwise your exception (from a
being non-existent global) will go uncaught and cause thread and app exit. Then, from that catch-all, you call sys.exc_info()
to get traceback info and sys.excepthook()
with the traceback info. This will send traceback to stderr (rather than stdout). So try for OutputWidget
:
def __init__(...):
...
sys.stdout = TextOutputSignal(textWritten=self.normalOutputWritten)
sys.stderr = TextOutputSignal(textWritten=self.errorOutputWritten)
...
def errorOutputWritten(self, text):
self.normalOutputWritten("*** ERROR: " + text)
and for your worker thread:
class Worker(QThread):
...
def run(self):
try:
# do some heavy work here
print 1 # 1 is printed in my OutputWidget
print a # a is not defined and it should print an error
except:
(type, value, traceback) = sys.exc_info()
sys.excepthook(type, value, traceback)
...decide if should exit thread or what...
In the above, the exception will cause thread to exit gracefully and you will see an error in console. In general, you will want to signal the main thread some error status too so that the application can determine what to do: show the user an error that network connectivity was lost, etc, and app must decide if it should exit, save work, whatever.
Note that if you have a couple specific exceptions that you want to deal with directly, like division by 0 or NameError
, you trap directly, and keep the catch-all for truely exceptional conditions (unexpected exceptions):
def run(self):
try:
# do some heavy work here
print 1 # 1 is printed in my OutputWidget
print a # a is not defined and it should print an error
except NameError, exc:
sys.stderr.write( "Name Error\n" );
...decide if should exit thread or what...
except:
(type, value, traceback) = sys.exc_info()
sys.excepthook(type, value, traceback)
...decide if should exit thread or what...