Wie kann ich alle Ausnahmen von einer WxPython Anwendung erfassen?
-
03-07-2019 - |
Frage
Ich bin ein wenig Debug-App für ein bisschen Kit schreiben wir entwickeln und ich möchte es auf ein paar Benutzer ausrollen, um zu sehen, ob sie irgendwelche Abstürze provozieren können. Kennt jemand eine Möglichkeit, effektiv eine WxPython App Einwickeln jegliche und alle nicht behandelten Ausnahmen zu fangen, die die App würde abstürzen?
Im Idealfall würde ich will alle Ausgaben (nicht nur Fehler) erfassen und protokollieren, die es in eine Datei. Etwaige Ausnahmen sollten nicht behandelte die aktuelle Datei protokollieren und lassen dann die Ausnahme weitergeben muß wie üblich (das heißt der Log-Prozess sollte transparent sein).
Ich bin sicher, dass jemand muss, bevor etwas in diese Richtung getan hat, aber ich habe nicht aufdrehen alles verwaltet, die über Google nützlich aussieht.
Lösung
Für die Standardausgabe Anmeldung können Sie einen stdout-Wrapper, wie diese verwendet werden:
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)
Sie müssen dann in Ihrem Haupt-Python-Datei initialisiert werden (die, die alles läuft):
import sys
sys.stdout = OutWrapper(sys.stdout, r'c:\temp\log.txt')
In Bezug auf die Protokollierung Ausnahmen, die einfachste Sache zu tun MainLoop
Methode der wx.App in einem try..except wickeln und dann die Ausnahmeinformationen extrahieren, sie in irgendeiner Weise speichern und dann die Ausnahme durch raise
re-raise , zum Beispiel:
try:
app.MainLoop()
except:
exc_info = sys.exc_info()
saveExcInfo(exc_info) # this method you have to write yourself
raise
Andere Tipps
Für die Ausnahmebehandlung, vorausgesetzt, Ihre Log-Datei wird als Protokoll geöffnet:
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
Sie können mit
sys.excepthook
(siehe Python docs )
und einige benutzerdefinierte Objekt zuweisen, die alle Ausnahmen abfangen würde früher in Ihrem Code nicht gefangen. Sie können dann melden Sie sich jede Nachricht auf jede Datei, die Sie zusammen mit Traceback und tun, was Sie mit der Ausnahme, wie (Reraise es, Fehlermeldung anzeigen und erlaubt dem Anwender, mit Ihrer App etc, um fortzufahren).
Wie für die Protokollierung stdout -. Der beste Weg für mich war so etwas wie DzinX des OutWrapper schreiben
Wenn Sie das Debuggen der Bühne sind, sollten Sie nach jeder Eingabe Ihre Log-Dateien zu spülen. Das schadet Leistung um eine Menge, aber wenn es Ihnen gelingt segfault in einigen zugrunde liegenden C-Code zu verursachen, Ihre Protokolle werden Sie nicht in die Irre führen.
Es gibt verschiedene Möglichkeiten. Sie können jedoch einen try..catch Block setzen in dem wxApplication :: OnInit, die nicht immer mit Gtk funktionieren würde.
Eine schöne Alternative wäre, die Anwendung :: Handle in Ihrem wxApplication abgeleiteten Klasse außer Kraft zu setzen, und einen Code wie folgt schreiben:
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()));
}
}
Es ist ein C ++ Beispiel, aber Sie können sicher auf Python leicht übersetzen.