2009-08-05 27 views
6

通常、処理されない例外はstdout(またはstderr?)に行きますが、シャットダウンしてユーザーに表示する前にGUIにこの情報を渡したいと思うアプリケーションを構築しています。ログファイルに保存します。だから、私は例外の全文でstrが必要です。Python:別の方法で未処理の例外を処理する方法はありますか?

どうすればいいですか?

答えて

0
try: 
    # blah blah The Main Loop, function, whatever... 
except e: 
    do_something_with(str(e)) 
+4

は、私はあなたが意味を推測... –

2
import sys, logging 

logging.basicConfig(filename='/path/to/log/file', filemode='w')  
... 

try: 
    your_code_here() 
except: 
    logging.exception("My code failed") # logs exception to file 
    # you define display_exception_in_ui as "def display_exception_in_ui(exc, tb):" 
    display_exception_in_ui(*sys.exc_info()[1:]) # passes exception instance, traceback 
15

使用は、ベース例外ハンドラを交換するsys.excepthook。あなたのような何かを行うことができます。

import sys 
from PyQt4 import QtGui 

import os.path 
import traceback 

def handle_exception(exc_type, exc_value, exc_traceback): 
    """ handle all exceptions """ 

    ## KeyboardInterrupt is a special case. 
    ## We don't raise the error dialog when it occurs. 
    if issubclass(exc_type, KeyboardInterrupt): 
    if QtGui.qApp: 
     QtGui.qApp.quit() 
    return 

    filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop() 
    filename = os.path.basename(filename) 
    error = "%s: %s" % (exc_type.__name__, exc_value) 

    QtGui.QMessageBox.critical(None,"Error", 
    "<html>A critical error has occured.<br/> " 
    + "<b>%s</b><br/><br/>" % error 
    + "It occurred at <b>line %d</b> of file <b>%s</b>.<br/>" % (line, filename) 
    + "</html>") 

    print "Closed due to an error. This is the full error report:" 
    print 
    print "".join(traceback.format_exception(exc_type, exc_value, exc_traceback)) 
    sys.exit(1) 



# install handler for exceptions 
sys.excepthook = handle_exception 

これは、すべての未処理の例外をキャッチするので、あなたのコードのトップレベルでブロックを除いて...しようとする必要はありません。

+2

それはメインスレッド内のすべての未処理の例外をキャッシュしていますが、threadingモジュールを使用する場合、threading.Threadは、ハンドラを除く/独自の試みを持っていますsys.excepthookを回避します。 http://bugs.python.org/issue1230540を参照してください。 – metamatt

9

あなたは既にすばらしい答えを得ています。私はちょうど、特定の問題「きれいに診断、ログなど、out of memoryのエラー?問題は、十分なオブジェクトが破棄されてメモリがリサイクルされる前にコードが制御された場合、メモリはプロパティロギング、GUIの作業などを行うにはあまりにもタイトすぎる可能性があります。

回答:あなたは、このような緊急時にそれを使うことができます知っているので、緊急スタッシュを構築:

rainydayfund = [[] for x in xrange(16*1024)] # or however much you need 

def handle_exception(e): 
    global rainydayfund 
    del rainydayfund 
    ... etc, etc ... 
0

私はNeil's answerを使用してみましたが、それはTkinterのGUIでは動作しません。そのためには、私はoverride report_callback_exception()だった。 「例外、E以外:」

import Tkinter as tk 
import tkMessageBox 
import traceback 

class MyApp(tk.Frame): 
    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent, *args, **kwargs) 
     parent.report_callback_exception = self.report_callback_exception 
     self.parent = parent 
     self.button_frame = tk.Frame(self) 
     self.button_frame.pack(side='top') 
     self.button_run = tk.Button(
      self.button_frame, text="Run", command=self.run 
     ) 
     self.button_run.grid(row=0, column=1, sticky='W') 

    def run(self): 
     tkMessageBox.showinfo('Info', 'The process is running.') 
     raise RuntimeError('Tripped.') 

    def report_callback_exception(self, exc_type, exc_value, exc_traceback): 
     message = ''.join(traceback.format_exception(exc_type, 
                exc_value, 
                exc_traceback)) 
     tkMessageBox.showerror('Error', message) 

def main(): 
    root = tk.Tk() # parent widget 

    MyApp(root).pack(fill='both', expand=True) 

    root.mainloop() # enter Tk event loop 

if __name__ == '__main__': 
    main() 
関連する問題