6

Я пишу небольшое отладочное приложение для небольшого набора, который мы разрабатываем, и я хотел бы развернуть его нескольким пользователям, чтобы узнать, могут ли они спровоцировать какие-либо сбои. Кто-нибудь знает способ эффективной упаковки приложения wxPython, чтобы поймать все необработанные исключения, которые могут привести к сбою приложения?Как я могу захватить все исключения из приложения wxPython?

В идеале я хотел бы захватить весь вывод (а не только ошибки) и записать его в файл. Любые необработанные исключения должны регистрироваться в текущем файле, а затем разрешать исключение, как обычно (т. Е. Процесс ведения журнала должен быть прозрачным).

Я уверен, что кто-то должен был что-то сделать в этих строках раньше, но мне не удалось найти что-нибудь полезное с помощью google.

ответ

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 метода wx.App в try..except, а затем извлечь информацию об исключении, сохранить его каким-то образом, а затем повторно установить исключение через raise, например:

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

Cheers Dzinx - я закончил использовать комбинацию вашего предложения и monopocalypse's – 2008-12-28 10:14:50

+3

Я попытался сделать это в своем приложении, чтобы поймать исключения и отобразить дружественные диалоговые окна ошибок, но это не сработало. Похоже, что поскольку wxPython генерирует другой поток для App.MainLoop(), исключения исключаются из области блока try/except в этой точке. – Soviut 2009-01-04 09:49:34

1

Существуют различные способы. Однако вы можете поместить блок try..catch в wxApplication :: OnInit, что не всегда будет работать с Gtk.

Хорошей альтернатива была бы переопределить Application :: 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)

и назначить для него некоторый пользовательский объект, который поймал бы все исключения, не обнаруженные ранее в вашем коде. Затем вы можете записывать любое сообщение в любой файл, который хотите, вместе с трассировкой и делать все, что угодно, с исключением (ререйзить, отобразить сообщение об ошибке и разрешить пользователю продолжать использовать ваше приложение и т. Д.).

Что касается регистрации stdout - лучшим способом для меня было написать нечто похожее на OutWrapper DzinX.

Если вы находитесь на стадии отладки, подумайте о том, чтобы очистить файлы журнала после каждой записи. Это сильно вредит производительности, но если вам удастся вызвать segfault в некотором базовом коде C, ваши журналы не будут вводить вас в заблуждение.

Смежные вопросы