2008-10-03 30 views
6

我正在爲一些我們正在開發的套件編寫一個小調試應用程序,我想將它推出給一些用戶,看他們是否會引發任何崩潰。有誰知道一種有效的方式來包裝一個wxPython應用程序來捕獲任何和所有可能導致應用程序崩潰的未處理的異常嗎?如何捕獲wxPython應用程序中的所有異常?

理想情況下,我想要捕獲所有輸出(不只是錯誤)並將其記錄到文件。任何未處理的異常都應該登錄到當前文件,然後允許異常按照慣例傳遞(即日誌記錄過程應該是透明的)。

我確定有人必須在這之前做過一些事情,但是我沒有設法通過谷歌提供任何看起來有用的東西。

回答

6

用於記錄標準輸出,你可以使用一個標準輸出的包裝,像這樣的:

from __future__ import with_statement 

class OutWrapper(object): 
    def __init__(self, realOutput, logFileName): 
     self._realOutput = realOutput 
     self._logFileName = logFileName 

    def _log(self, text): 
     with open(self._logFileName, 'a') as logFile: 
      logFile.write(text) 

    def write(self, text): 
     self._log(text) 
     self._realOutput.write(text) 

然後你在你的主要的Python文件並進行初始化(運行一切的一個):

import sys  
sys.stdout = OutWrapper(sys.stdout, r'c:\temp\log.txt') 

至於日誌記錄異常,最簡單的做法是將wx.App的MainLoop方法包裝在try..except中,然後提取異常信息並以某種方式保存,然後重新引發異常raise,例如:

try: 
    app.MainLoop() 
except: 
    exc_info = sys.exc_info() 
    saveExcInfo(exc_info) # this method you have to write yourself 
    raise 
+0

乾杯Dzinx - 最後我用你的建議和monopocalypse的 – 2008-12-28 10:14:50

+3

我試圖以捕捉異常並顯示友好的錯誤對話框,在我的應用程序這樣的組合,但沒有奏效。看起來,因爲wxPython爲App.MainLoop()產生了一個不同的線程,以至於異常超出了try/except塊的範圍。 – Soviut 2009-01-04 09:49:34

1

有很多種方法。你可以在wxApplication :: OnInit中放一個try..catch塊,但是,這並不總是適用於Gtk。

一個不錯的選擇將是重寫應用程序::爲handleEvent在wxApplication派生類,並寫了這樣的代碼:

void Application::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& event) const 
{ 
    try 
    { 
     wxAppConsole::HandleEvent(handler, func, event); 
    } 
    catch (const std::exception& e) 
    { 
     wxMessageBox(std2wx(e.what()), _("Unhandled Error"), 
      wxOK | wxICON_ERROR, wxGetTopLevelParent(wxGetActiveWindow())); 
    } 
} 

這是一個C++的例子,但你一定能夠轉化爲Python的容易。

9

對於異常處理,假設你的日誌文件被打開日誌:

import sys 
import traceback 

def excepthook(type, value, tb): 
    message = 'Uncaught exception:\n' 
    message += ''.join(traceback.format_exception(type, value, tb)) 
    log.write(message) 

sys.excepthook = excepthook 
3

您可以使用

sys.excepthook

(見Python docs

併爲其分配一些自定義對象,這將捕獲您的代碼中以前未捕獲的所有異常。然後,您可以將任何消息記錄到您希望的任何文件中,並與traceback一起執行任何您喜歡的操作(重新顯示它,顯示錯誤消息並允許用戶繼續使用您的應用程序等)。

至於記錄標準輸出 - 對我來說最好的方法是寫一些類似於DzinX的OutWrapper。

如果您處於調試階段,請考慮在每次輸入後清空日誌文件。這會對性能造成很大影響,但是如果您在某些底層C代碼中設法引起段錯誤,則日誌不會誤導您。

相關問題