Source code for pisak.hooks
"""
Various global hooks.
"""
import sys
import threading
import traceback
from pisak import logger
_LOG = logger.get_logger(__file__)
_MESSAGES = {
"unexpected_error": "Wystąpił nieoczekiwany błąd.\n"
"Aplikacja zostanie zamknięta."
}
def _register_custom_excepthook():
"""
Register custom function to be used as sys.excepthook for
the current application. It will: handle any exception that
has not been caught by the application
itself; log the error as critical; if the application main loop is still
alive then display some GUI message and then close the application,
otherwise just do nothing and let the application close itself; only
exceptions originating from the main thread are handled;
call the default, built-in `sys.__excepthook__` function in the end.
"""
def excepthook(exctype, value, traceb):
import pisak
if exctype in (KeyboardInterrupt, SystemExit):
pass
else:
_LOG.critical(''.join(traceback.format_exception(
exctype, value, traceb)))
if (isinstance(threading.currentThread(),
threading.main_thread().__class__) and
pisak.app is not None and
pisak.app.main_loop_is_running):
try:
pisak.app.window.load_popup(
_MESSAGES["unexpected_error"], pisak.app.main_quit)
except Exception as exc:
_LOG.critical(exc)
sys.__excepthook__(exctype, value, traceb)
sys.excepthook = excepthook
def _register_thread_excepthook():
"""
Monkey patch the `threading.Thread.run` method in order to catch
all the uncaught exceptions that happened in a thread with
an exception hook.
"""
init_old = threading.Thread.__init__
def init(self, *args, **kwargs):
init_old(self, *args, **kwargs)
run_old = self.run
def run_with_except_hook(*args, **kw):
try:
run_old(*args, **kw)
except:
sys.excepthook(*sys.exc_info())
self.run = run_with_except_hook
threading.Thread.__init__ = init
def _register_custom_print_exception():
"""
Monkey patch the `traceback.print_exception` function in order to log
information about all the incoming exceptions, before printing them.
"""
print_exception_old = traceback.print_exception
def print_exception(exctype, value, traceb, limit=None, file=None, chain=True):
_LOG.error(''.join(traceback.format_exception(
exctype, value, traceb, limit, chain)))
print_exception_old(exctype, value, traceb, limit, file, chain)
traceback.print_exception = print_exception
[docs]def init_hooks():
"""
Register all the hooks. Should be called as soon as a program starts.
"""
_register_custom_excepthook()
_register_thread_excepthook()
_register_custom_print_exception()