Как я могу зафиксировать все исключения из приложения wxPython?

StackOverflow https://stackoverflow.com/questions/166198

Вопрос

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

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

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

Это было полезно?

Решение

Для регистрации стандартного вывода вы можете использовать оболочку стандартного вывода, например, такую:

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')

Что касается регистрации исключений, самое простое - это обернуть метод MainLoop файла wx.App в try..except, затем извлечь информацию об исключении, сохранить ее каким-либо образом, а затем повторно вызвать исключение с помощью повысить , например:

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

Другие советы

Для обработки исключений, предположим, что ваш файл журнала открыт как журнал:

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

Вы можете использовать

системный.excepthook

(см . Документы на Python)

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

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

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

Есть разные способы. Вы можете поместить блок 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top