如何捕获wxPython应用中的所有异常?

7 投票
4 回答
4675 浏览
提问于 2025-04-11 09:25

我正在为我们正在开发的一款设备写一个小调试应用,想把它发给一些用户,看看他们能否引发任何崩溃。有没有人知道怎么有效地包装一个wxPython应用,以捕捉所有未处理的异常,这些异常会导致应用崩溃?

理想情况下,我希望能捕获所有输出(不仅仅是错误),并将其记录到一个文件中。任何未处理的异常都应该记录到当前文件,然后让异常像往常一样继续传递(也就是说,记录过程应该是透明的)。

我相信之前一定有人做过类似的事情,但我通过谷歌搜索并没有找到看起来有用的内容。

4 个回答

3

你可以使用

sys.excepthook

(详细内容可以查看Python文档

然后你可以给它指定一个自定义的对象,这样就能捕捉到你代码中之前没有处理的所有异常。这样你就可以把任何信息记录到你想要的文件里,包括错误追踪信息,并且可以对异常进行各种处理(比如重新抛出异常、显示错误信息让用户继续使用你的应用等等)。

至于记录标准输出,最好的方法对我来说是写一个类似于DzinX的OutWrapper的东西。

如果你在调试阶段,考虑在每次写入日志后刷新日志文件。这样会影响性能,但如果你在某些底层C代码中引发了段错误,你的日志就不会误导你。

11

关于异常处理,假设你的日志文件已经打开,并且命名为 log:

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
6

如果你想记录标准输出的信息,可以使用一个叫做stdout包装器的工具,比如下面这个:

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

撰写回答