Domanda

Sto scrivendo una piccola app di debug per un po 'di kit che stiamo sviluppando e vorrei distribuirlo ad alcuni utenti per vedere se possono provocare crash. Qualcuno conosce un modo per racchiudere in modo efficace un'app wxPython per rilevare eventuali eccezioni non gestite che potrebbero causare il crash dell'app?

Idealmente vorrei catturare tutto l'output (non solo errori) e registrarlo in un file. Eventuali eccezioni non gestite devono accedere al file corrente e quindi consentire che l'eccezione venga trasmessa come al solito (ad esempio, il processo di registrazione deve essere trasparente).

Sono sicuro che qualcuno deve aver fatto qualcosa del genere prima d'ora, ma non sono riuscito a trovare nulla che appaia utile tramite Google.

È stato utile?

Soluzione

Per la registrazione dell'output standard, è possibile utilizzare un wrapper stdout, come questo:

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)

Devi quindi inizializzarlo nel tuo file Python principale (quello che esegue tutto):

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

Per quanto riguarda la registrazione delle eccezioni, la cosa più semplice da fare è racchiudere il metodo MainLoop di wx.App in un try..except, quindi estrarre le informazioni sull'eccezione, salvarle in qualche modo e quindi ri-sollevare l'eccezione tramite raise , ad esempio:

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

Altri suggerimenti

Per la gestione delle eccezioni, supponendo che il file di registro sia aperto come registro:

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

Puoi usare

  

sys.excepthook

(vedi Python docs )

e assegnargli un oggetto personalizzato, che catturerebbe tutte le eccezioni non rilevate in precedenza nel codice. È quindi possibile registrare qualsiasi messaggio su qualsiasi file desiderato, insieme a traceback e fare ciò che si desidera con l'eccezione (rialzarlo, visualizzare un messaggio di errore e consentire all'utente di continuare a utilizzare l'app ecc.)

Per quanto riguarda la registrazione di stdout, il modo migliore per me è stato scrivere qualcosa di simile a OutWrapper di DzinX.

Se sei in fase di debug, considera di scaricare i file di registro dopo ogni voce. Ciò danneggia molto le prestazioni, ma se riesci a causare segfault in alcuni codici C sottostanti, i tuoi registri non ti indurranno in errore.

Esistono vari modi. Puoi mettere un blocco try..catch in wxApplication :: OnInit, tuttavia, che non funzionerebbe sempre con Gtk.

Una buona alternativa sarebbe quella di sovrascrivere Application :: HandleEvent nella classe derivata da wxApplication e scrivere un codice come questo:

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()));
    }
}

È un esempio in C ++, ma puoi sicuramente tradurre facilmente in Python.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top