Question

J'écris une petite application de débogage pour un peu de kit que nous développons et j'aimerais la transmettre à quelques utilisateurs pour voir s'ils peuvent provoquer des plantages. Est-ce que quelqu'un connaît un moyen d'encapsuler efficacement une application wxPython pour intercepter toutes les exceptions non gérées qui provoqueraient le blocage de l'application?

Idéalement, je souhaiterais capturer toutes les sorties (pas seulement les erreurs) et les enregistrer dans un fichier. Toutes les exceptions non gérées doivent se connecter au fichier actuel, puis permettre à l’exception de se transmettre comme à l’habitude (c’est-à-dire que le processus de journalisation doit être transparent).

Je suis sûr que quelqu'un a déjà fait quelque chose dans ce sens auparavant, mais je n'ai pas réussi à trouver quoi que ce soit qui paraisse utile via Google.

Était-ce utile?

La solution

Pour consigner la sortie standard, vous pouvez utiliser un wrapper stdout, tel que celui-ci:

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)

Vous devez ensuite l'initialiser dans votre fichier Python principal (celui qui exécute tout):

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

En ce qui concerne la journalisation des exceptions, la solution la plus simple consiste à envelopper la méthode MainLoop de wx.App dans un essai..exception, puis à extraire les informations sur l'exception, à les enregistrer d'une certaine manière, puis relancez l'exception avec raise , par exemple:

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

Autres conseils

Pour la gestion des exceptions, en supposant que votre fichier journal est ouvert en tant que journal:

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

Vous pouvez utiliser

  

sys.excepthook

(voir documents Python )

et lui attribuer un objet personnalisé, qui intercepterait toutes les exceptions non détectées plus tôt dans votre code. Vous pouvez ensuite consigner n'importe quel message dans n'importe quel fichier, avec trace, et faire ce que bon vous semble avec l'exception (relancez-le, affichez le message d'erreur et laissez l'utilisateur continuer à utiliser votre application, etc.).

En ce qui concerne la journalisation de stdout - le meilleur moyen pour moi consistait à écrire quelque chose de similaire à OutWrapper de DzinX.

Si vous en êtes au stade du débogage, envisagez de vider vos fichiers journaux après chaque entrée. Cela nuit beaucoup aux performances, mais si vous parvenez à causer une erreur de segmentation dans du code C sous-jacent, vos journaux ne vous induiront pas en erreur.

Il y a différentes manières. Vous pouvez mettre un bloc try..catch dans wxApplication :: OnInit, cependant, cela ne fonctionnerait pas toujours avec Gtk.

Une bonne alternative serait de surcharger Application :: HandleEvent dans votre classe dérivée wxApplication et d'écrire un code comme celui-ci:

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’est un exemple C ++, mais vous pouvez sûrement traduire facilement en Python.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top