1""" 2Exception hook 3If some unexpected error occures it can be shown in a nice looking dialog. 4Especially useful is the traceback view. 5 6Things to extend: Clicking on the filename should open an editor. 7Things to consider: Mail exceptions, copy to clipboard or send to bug tracker. 8""" 9import sys 10import cgitb 11import atexit 12 13from PyQt4.QtCore import pyqtSignature, Qt 14from PyQt4.QtGui import QDialog, QApplication 15 16from excepthook_ui import Ui_ExceptHookDialog 17 18 19 20def on_error(exc_type, exc_obj, exc_tb): 21 """ 22 This is the callback function for sys.excepthook 23 """ 24 dlg = ExceptHookDialog(exc_type, exc_obj, exc_tb) 25 dlg.show() 26 dlg.exec_() 27 28 29 30def show_current_error(title=None): 31 """ 32 Call this function to show the current error. 33 It can be used inside an except-block. 34 """ 35 dlg = ExceptHookDialog(sys.exc_type, sys.exc_value, sys.exc_traceback, title) 36 dlg.show() 37 dlg.exec_() 38 39 40def install(): 41 "activates the error handler" 42 sys.excepthook = on_error 43 44 45 46def uninstall(): 47 "removes the error handler" 48 sys.excepthook = sys.__excepthook__ 49 50atexit.register(uninstall) 51 52 53class ExceptHookDialog(QDialog): 54 55 56 def __init__(self, exc_type, exc_obj, exc_tb, title=None): 57 QDialog.__init__(self) 58 self.ui = Ui_ExceptHookDialog() 59 self.ui.setupUi(self) 60 if title: 61 self.setWindowTitle(self.windowTitle() + ": " + title) 62 self.ui.detailsButton.setCheckable(True) 63 self.setExtension(self.ui.tracebackBrowser) 64 self.setOrientation(Qt.Vertical) 65 msg = "%s: %s" % (exc_type.__name__, exc_obj) 66 self.ui.exceptionLabel.setText(msg) 67 html = cgitb.html((exc_type, exc_obj, exc_tb)) 68 self.ui.tracebackBrowser.setText(html) 69 self.resize(self.sizeHint()) 70 71 72 @pyqtSignature("") 73 def on_closeButton_clicked(self): 74 self.close() 75 76 77 @pyqtSignature("") 78 def on_detailsButton_clicked(self): 79 self.showExtension(self.ui.detailsButton.isChecked()) 80 81 82 83if __name__ == "__main__": 84 # Some tests: 85 app = QApplication(sys.argv) 86 install() 87 print "Triggering error 1" 88 try: 89 fail = 1 / 0 90 except: 91 show_current_error("Using inside except") 92 print "Triggering error 2" 93 fail2 = 1 / 0 94 print "This will never be reached because excepthook" 95 print "complains about fail2" 96