Open TobiasSpohn opened 1 month ago
Well as long as we are not providing "manual" logging by wrapping everything in try-except, this is a problem in PySide2
. The PySide2
excepthook does not register exceptions raised in threaded slots.
Regarding your examples... the proper way to "manually" log exceptions in qudi
would be:
try:
...
except:
self.log.exception('Something went wrong')
raise
This will log the full exception traceback and re-raise any exception without alteration.
Yes, this is the better way to log the exception. Thanks, I changed the files.
Do you think it is possible and does it make sense to modify the base class so that every method does this wrapping by default? Then at least all exceptions will be logged so the user can deal with it and the exceptions not just "vanish".
Possible, yes. But it comes with quite a large overhead that impacts performance of almost anything in qudi
. Each call to a logic method and property will require a check if the caller is the main thread and only wrap the call in try-except if this is not the case.
Before we commit to such drastic workarounds, I would like to check first if this issue has been resolved in PySide6
.
Version
Development
What is affected by the bug?
Any module that uses QtCore.Qt.QueuedConnection to call a method from any other thread (module).
When does the bug occur?
When using Qt's QueuedConnection to call a method of a different thread. If the called method raises an exception that exception is never logged nor printed to console. This can be very confusing when testing new modules as no exceptions are thrown when some call fails.
How do we replicate the issue?
I provided a minimal working example in branch
no_exception_logging
no_exception_logging
src/exception.cfg
problem_logic.connect_signal(1)
problem_logic.emit_signal()
orproblem_logic.connect_signal(3)
problem_logic.emit_signal()
Expected behavior
The logger should log the exception
Exception in exception_method
. Maybe even the traceback for easier identification where the exception occured.If calling
problem_logic.connect_signal(2)
problem_logic.emit_signal()
orproblem_logic.connect_signal(4)
problem_logic.emit_signal()
the exception is correctly logged.Relevant log output
Additional Comments
The resolution to this problem is to wrap the whole method body of the called method into a try, except statement. This is done by using
ExceptionLogic.try_except_method
as slot method. Or assign a slot method that calls the function in the other thread within a try, except statement. This is done by utilizingProblemLogic.test_try_except_exception_method
as slot method.Maybe it makes sense to write a wrapper in some Base class that does this automatically.
Furthermore, is it possible to not only log the exception message
Exception in exception_method
but also the full traceback to simplify the search for what caused the exception?Contact Details
No response