[PyQt] Exception handling hook

Detlev Offenbach detlev at die-offenbachs.de
Fri May 25 17:36:16 BST 2007


On Donnerstag, 24. Mai 2007, Arve Knudsen wrote:
> Hi Detlev
>
> On 5/24/07, Detlev Offenbach <detlev at die-offenbachs.de> wrote:
> > On Mittwoch, 23. Mai 2007, Arve Knudsen wrote:
> > > Is it possible to register a hook with QApplication in order to be
> >
> > notified
> >
> > > of an unhandled exception? Currently, all that happens when an
> > > exception propagates to the event loop is that it gets printed in the
> > > console,
> >
> > which
> >
> > > is not very helpful. How do others cope with unhandled exceptions in
> >
> > PyQt
> >
> > > applications?
> > >
> > > Best regards,
> > > Arve Knudsen
> >
> > See eric4 as an example.
>
> I'm not at all familiar with eric4. Could you please elaborate as to where
> I can look in eric4's source code (I assume this is what you mean)? Also, I
> take it eric4 does something more advanced than override sys.excepthook?
>
> Thanks,
> Arve
>
> Detlev
>
> > --
> > Detlev Offenbach
> > detlev at die-offenbachs.de

Hi,

here is the code sample to illustrate how it is done in eric4.

-------------------------
def excepthook(excType, excValue, tracebackobj):
    """
    Global function to catch unhandled exceptions.
    
    @param excType exception type
    @param excValue exception value
    @param tracebackobj traceback object
    """
    separator = '-' * 80
    logFile = 
os.path.join(unicode(Utilities.getConfigDir()), "eric4_error.log")
    notice = \
        """An unhandled exception occurred. Please report the problem"""\
        """ using the error reporting dialog or via email to <%s>."""\
        """ A log has been written to "%s".\n\nError information:\n""" % \
        (BugAddress, logFile)
    timeString = time.strftime("%Y-%m-%d, %H:%M:%S")
    
    try:
        import sipconfig
        sip_version_str = sipconfig.Configuration().sip_version_str
    except ImportError:
        sip_version_str = "sip version not available"
    if KdeQt.isKDE():
        versionInfo = ("\n%s\nVersion Numbers:\n  Python %s\n" + \
            "  KDE %s\n  PyKDE %s\n  Qt %s\n" + \
            "  PyQt4 %s\n  sip %s\n  QScintilla %s\n  %s %s\n" + \
            "  Bicycle Repair Man %s\n\nPlatform: %s\n%s\n") % \
            (separator, sys.version.split()[0],
            str(KdeQt.kdeVersionString()), str(KdeQt.pyKdeVersionString()),
            str(qVersion()), str(PYQT_VERSION_STR), str(sip_version_str),
            str(QSCINTILLA_VERSION_STR),
            Program, Version, BRM_VERSION_STR, sys.platform, sys.version)
    else:
        versionInfo = ("\n%s\nVersion Numbers:\n  Python %s\n  Qt %s\n" + \
            "  PyQt4 %s\n  sip %s\n  QScintilla %s\n  %s %s\n" + \
            "  Bicycle Repair Man %s\n\nPlatform: %s\n%s\n") % \
            (separator, sys.version.split()[0],
            str(qVersion()), str(PYQT_VERSION_STR), str(sip_version_str),
            str(QSCINTILLA_VERSION_STR),
            Program, Version, BRM_VERSION_STR, sys.platform, sys.version)
    tbinfofile = StringIO()
    traceback.print_tb(tracebackobj, None, tbinfofile)
    tbinfofile.seek(0)
    tbinfo = tbinfofile.read()
    errmsg = '%s: \n%s' % (str(excType), str(excValue))
    sections = [separator, timeString, separator, errmsg, separator, tbinfo]
    msg = '\n'.join(sections)
    try:
        f = open(logFile, "w")
        f.write(msg)
        f.write(versionInfo)
        f.close()
    except IOError:
        pass
    qWarning(str(notice) + msg)

def main():
    """
    Main entry point into the application.
    """
    sys.excepthook = excepthook
--------------------------------

It includes more stuff than the plain error handling, but you should be able 
to figure out the relevant parts. The last thing it does is calling qWarning. 
This will print the string in the console, if no event loop is running yet, 
in a dialog window otherwise.

Hope this helps a bit.

Detlev
-- 
Detlev Offenbach
detlev at die-offenbachs.de


More information about the PyQt mailing list