[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    [PyQt] Uncaught exceptions
From:       slepton () posteo ! de
Date:       2020-02-16 14:24:58
Message-ID: 964d5ff3f0714d6cd58051a2d16bb702 () posteo ! de
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


 Hello,

in the past I had some trouble with uncaught exception (e.g. PyCharm
does not show the traceback, at least not without further adjustments,
without console output the information is lost, ...). There are many
posts on Stackoverflow and else where, based on
timlehr.com/python-exception-hooks-with-qt-message-box/ [1]and
fman.io/blog/pyqt-excepthook/ [2]the solution below suits all my needs
and might be be usefull to others. 

Cheers 

Sebastian

import logging
import sys
import traceback
import datetime

from PyQt5.QtCore import QObject
from PyQt5.QtWidgets import QApplication, QMessageBox

from collections import namedtuple

fake_tb = namedtuple('fake_tb', ('tb_frame', 'tb_lasti', 'tb_lineno',
'tb_next'))

class UncaughtHook(QObject):
 """Show exceptions in a QMessageBox and add missing frames to the trace

 Usage example:
 --------------
 import sys
 from PyQt5.QtWidgets import QApplication
 uncaught_hook_handler = UncaughtHook() 
 # Setting the hook first, import errors (e.g. missing modules) 
 # will be caught and shown graphically as well
 sys.excepthook = uncaught_hook_handler.exception_hook

 app = QApplication([])
 if __name__ == '__main__':
 form your_application import Window
 window = Window()
 window.show()
 app.exec()

 This is based on Exception handling code with popups by Tim Lehr
 http://timlehr.com/python-exception-hooks-with-qt-message-box/
 and "adding missing frames" by Michael Herrmann
 https://fman.io/blog/pyqt-excepthook/
 please see original posts for details and examples.
 """

 def __init__(self, *args, **kwargs):
 super(UncaughtHook, self).__init__(*args, **kwargs)
 self.log = logging.getLogger(__name__)
 self.handler = logging.StreamHandler(stream=sys.stdout)
 self.log.addHandler(self.handler)

 def exception_hook(self, exc_type, exc_value, exc_traceback):
 """Custom except hook, showing a QMessageBox if possible."""
 exc_traceback = self._add_missing_frames(exc_traceback) if
exc_traceback else exc_traceback
 # Allow debugging of non-gui applications
 if not issubclass(exc_type, KeyboardInterrupt) and
QApplication.instance() is not None:

 log_msg = 'n'.join([''.join(traceback.format_tb(exc_traceback)),
 '{0}: {1}'.format(exc_type.__name__, exc_value)])
 # Uncomment lines below when logging to a file is enabled
 # exc_info = (exc_type, exc_value, exc_traceback)
 # self.log.critical("Uncaught exception:n {0}".format(log_msg),
exc_info=exc_info)
 reply = QMessageBox.critical(None, 'Uncaught Exception, closing
application ...',
 str(log_msg), QMessageBox.Save | QMessageBox.No)
 # Comment lines below when logging to a file is enabled
 # Otherwise the user can save a crash report
 if reply == QMessageBox.Save:
 log_file =
datetime.datetime.now().strftime('Crash_report-%Y-%m-%d_%H-%M-%S.log')
 with open(log_file, 'w') as fh:
 fh.write(log_msg)
 print('SAVED CRASH REPORT TO', Path(log_file).absolute())
 traceback.print_exception(exc_type, exc_value, exc_traceback)
 sys.exit(-1)

 @staticmethod
 def _add_missing_frames(tb):
 result = fake_tb(tb.tb_frame, tb.tb_lasti, tb.tb_lineno, tb.tb_next)
 frame = tb.tb_frame.f_back
 while frame:
 result = fake_tb(frame, frame.f_lasti, frame.f_lineno, result)
 frame = frame.f_back
 return result

 

Links:
------
[1] http://timlehr.com/python-exception-hooks-with-qt-message-box/%20
[2] https://fman.io/blog/pyqt-excepthook/

[Attachment #5 (unknown)]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<html><body style='font-size: 10pt; font-family: Verdana,Geneva,sans-serif'>
Hello,<br /><br />in the past I had some trouble with uncaught exception (e.g.&nbsp; \
PyCharm does not show the traceback, at least not without further adjustments, \
without console output the information is lost, ...). There are many posts on \
Stackoverflow and else where, based on <a \
title="http://timlehr.com/python-exception-hooks-with-qt-message-box/ " \
href="http://timlehr.com/python-exception-hooks-with-qt-message-box/%20">timlehr.com/python-exception-hooks-with-qt-message-box/ \
</a>and <a title="https://fman.io/blog/pyqt-excepthook/" \
href="https://fman.io/blog/pyqt-excepthook/">fman.io/blog/pyqt-excepthook/ </a>the \
solution below suits all my needs and might be be usefull to others. <br /><br \
/>Cheers <br /><br />Sebastian<br /><br /><br /> <pre style="background-color: \
#2b2b2b; color: #a9b7c6; font-family: 'Consolas'; font-size: 9,8pt;"><span \
style="color: #cc7832;">import </span>logging<br /><span style="color: \
#cc7832;">import </span>sys<br /><span style="color: #cc7832;">import \
</span>traceback<br /><span style="color: #cc7832;">import </span>datetime<br /><br \
/><span style="color: #cc7832;">from </span>PyQt5.QtCore <span style="color: \
#cc7832;">import </span>QObject<br /><span style="color: #cc7832;">from \
</span>PyQt5.QtWidgets <span style="color: #cc7832;">import </span>QApplication<span \
style="color: #cc7832;">, </span>QMessageBox<br /><br /><span style="color: \
#cc7832;">from </span>collections <span style="color: #cc7832;">import \
</span>namedtuple<br /><br />fake_tb = namedtuple(<span style="color: \
#6a8759;">'fake_tb'</span><span style="color: #cc7832;">, </span>(<span style="color: \
#6a8759;">'tb_frame'</span><span style="color: #cc7832;">, </span><span style="color: \
#6a8759;">'tb_lasti'</span><span style="color: #cc7832;">, </span><span style="color: \
#6a8759;">'tb_lineno'</span><span style="color: #cc7832;">, </span><span \
style="color: #6a8759;">'tb_next'</span>))<br /><br /><br /><span style="color: \
#cc7832;">class </span>UncaughtHook(QObject):<br />    <span style="color: #629755; \
font-style: italic;">"""Show exceptions in a QMessageBox and add missing frames to \
the trace<br /></span><span style="color: #629755; font-style: italic;">    <br \
/></span><span style="color: #629755; font-style: italic;">    Usage example:<br \
/></span><span style="color: #629755; font-style: italic;">    --------------<br \
/></span><span style="color: #629755; font-style: italic;">    import sys<br \
/></span><span style="color: #629755; font-style: italic;">    from PyQt5.QtWidgets \
import QApplication<br /></span><span style="color: #629755; font-style: italic;">    \
uncaught_hook_handler = UncaughtHook()  <br /></span><span style="color: #629755; \
font-style: italic;">    # Setting the hook first, import errors (e.g. missing \
modules) <br /></span><span style="color: #629755; font-style: italic;">    # will be \
caught and shown graphically as well<br /></span><span style="color: #629755; \
font-style: italic;">    sys.excepthook = uncaught_hook_handler.exception_hook<br \
/></span><span style="color: #629755; font-style: italic;"><br /></span><span \
style="color: #629755; font-style: italic;">    app = QApplication([])<br \
/></span><span style="color: #629755; font-style: italic;">    if __name__ == \
'__main__':<br /></span><span style="color: #629755; font-style: italic;">        \
form your_application import Window<br /></span><span style="color: #629755; \
font-style: italic;">        window = Window()<br /></span><span style="color: \
#629755; font-style: italic;">        window.show()<br /></span><span style="color: \
#629755; font-style: italic;">        app.exec()<br /></span><span style="color: \
#629755; font-style: italic;">        <br /></span><span style="color: #629755; \
font-style: italic;">    This is based on Exception handling code with popups by Tim \
Lehr<br /></span><span style="color: #629755; font-style: italic;">        \
http://timlehr.com/python-exception-hooks-with-qt-message-box/<br /></span><span \
style="color: #629755; font-style: italic;">    and "adding missing frames" by \
Michael Herrmann<br /></span><span style="color: #629755; font-style: italic;">       \
https://fman.io/blog/pyqt-excepthook/<br /></span><span style="color: #629755; \
font-style: italic;">    please see original posts for details and examples.<br \
/></span><span style="color: #629755; font-style: italic;">    """<br /></span><span \
style="color: #629755; font-style: italic;"><br /></span><span style="color: #629755; \
font-style: italic;">    </span><span style="color: #cc7832;">def </span><span \
style="color: #b200b2;">__init__</span>(<span style="color: \
#94558d;">self</span><span style="color: #cc7832;">, </span>*args<span style="color: \
#cc7832;">, </span>**kwargs):<br />        <span style="color: \
#8888c6;">super</span>(UncaughtHook<span style="color: #cc7832;">, </span><span \
style="color: #94558d;">self</span>).<span style="color: \
#b200b2;">__init__</span>(*args<span style="color: #cc7832;">, </span>**kwargs)<br /> \
<span style="color: #94558d;">self</span>.log = logging.getLogger(__name__)<br />     \
<span style="color: #94558d;">self</span>.handler = logging.StreamHandler(<span \
style="color: #aa4926;">stream</span>=sys.stdout)<br />        <span style="color: \
#94558d;">self</span>.log.addHandler(<span style="color: \
#94558d;">self</span>.handler)<br /><br />    <span style="color: #cc7832;">def \
</span><span style="color: #ffc66d;">exception_hook</span>(<span style="color: \
#94558d;">self</span><span style="color: #cc7832;">, </span>exc_type<span \
style="color: #cc7832;">, </span>exc_value<span style="color: #cc7832;">, \
</span>exc_traceback):<br />        <span style="color: #629755; font-style: \
italic;">"""Custom except hook, showing a QMessageBox if possible."""<br \
/></span><span style="color: #629755; font-style: italic;">        \
</span>exc_traceback = <span style="color: \
#94558d;">self</span>._add_missing_frames(exc_traceback) <span style="color: \
#cc7832;">if </span>exc_traceback <span style="color: #cc7832;">else \
</span>exc_traceback<br />        <span style="color: #808080;"># Allow debugging of \
non-gui applications<br /></span><span style="color: #808080;">        </span><span \
style="color: #cc7832;">if not </span><span style="color: \
#8888c6;">issubclass</span>(exc_type<span style="color: #cc7832;">, </span><span \
style="color: #8888c6;">KeyboardInterrupt</span>) <span style="color: #cc7832;">and \
</span>QApplication.instance() <span style="color: #cc7832;">is not None</span>:<br \
/><br />            log_msg = <span style="color: #6a8759;">'</span><span \
style="color: #cc7832;">\n</span><span style="color: #6a8759;">'</span>.join([<span \
style="color: #6a8759;">''</span>.join(traceback.format_tb(exc_traceback))<span \
style="color: #cc7832;">,<br /></span><span style="color: #cc7832;">                  \
</span><span style="color: #6a8759;">'{0}: {1}'</span>.format(exc_type.<span \
style="color: #b200b2;">__name__</span><span style="color: #cc7832;">, \
</span>exc_value)])<br />            <span style="color: #808080;"># Uncomment lines \
below when logging to a file is enabled<br /></span><span style="color: #808080;">    \
# exc_info = (exc_type, exc_value, exc_traceback)<br /></span><span style="color: \
#808080;">            # self.log.critical("Uncaught exception:\n \
{0}".format(log_msg), exc_info=exc_info)<br /></span><span style="color: #808080;">   \
</span>reply = QMessageBox.critical(<span style="color: #cc7832;">None, </span><span \
style="color: #6a8759;">'Uncaught Exception, closing application ...'</span><span \
style="color: #cc7832;">,<br /></span><span style="color: #cc7832;">                  \
</span><span style="color: #8888c6;">str</span>(log_msg)<span style="color: \
#cc7832;">, </span>QMessageBox.Save | QMessageBox.No)<br />            <span \
style="color: #808080;"># Comment lines below when logging to a file is enabled<br \
/></span><span style="color: #808080;">            # Otherwise the user can save a \
crash report<br /></span><span style="color: #808080;">            </span><span \
style="color: #cc7832;">if </span>reply == QMessageBox.Save:<br />                \
log_file = datetime.datetime.now().strftime(<span style="color: \
#6a8759;">'Crash_report-%Y-%m-%d_%H-%M-%S.log'</span>)<br />                <span \
style="color: #cc7832;">with </span><span style="color: \
#8888c6;">open</span>(log_file<span style="color: #cc7832;">, </span><span \
style="color: #6a8759;">'w'</span>) <span style="color: #cc7832;">as </span>fh:<br /> \
fh.write(log_msg)<br />                <span style="color: \
#8888c6;">print</span>(<span style="color: #6a8759;">'SAVED CRASH REPORT \
TO'</span><span style="color: #cc7832;">, </span>Path(log_file).absolute())<br />     \
traceback.print_exception(exc_type<span style="color: #cc7832;">, \
</span>exc_value<span style="color: #cc7832;">, </span>exc_traceback)<br />        \
sys.exit(-<span style="color: #6897bb;">1</span>)<br /><br />    <span style="color: \
#bbb529;">@staticmethod<br /></span><span style="color: #bbb529;">    </span><span \
style="color: #cc7832;">def </span><span style="color: \
#ffc66d;">_add_missing_frames</span>(tb):<br />        result = \
fake_tb(tb.tb_frame<span style="color: #cc7832;">, </span>tb.tb_lasti<span \
style="color: #cc7832;">, </span>tb.tb_lineno<span style="color: #cc7832;">, \
</span>tb.tb_next)<br />        frame = tb.tb_frame.f_back<br />        <span \
style="color: #cc7832;">while </span>frame:<br />            result = \
fake_tb(frame<span style="color: #cc7832;">, </span>frame.f_lasti<span style="color: \
#cc7832;">, </span>frame.f_lineno<span style="color: #cc7832;">, </span>result)<br /> \
frame = frame.f_back<br />        <span style="color: #cc7832;">return \
</span>result<br /><br /><br /></pre> </body></html>


[Attachment #6 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
https://www.riverbankcomputing.com/mailman/listinfo/pyqt


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic