2008-10-03 31 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代码中设法引起段错误,则日志不会误导您。

相关问题