2008-10-03 34 views
6

Estoy escribiendo una pequeña aplicación de depuración para un kit que estamos desarrollando y me gustaría extenderlo a algunos usuarios para ver si pueden provocar algún bloqueo. ¿Alguien sabe cómo envolver efectivamente una aplicación wxPython para detectar todas y cada una de las excepciones no controladas que causarían la falla de la aplicación?¿Cómo puedo capturar todas las excepciones de una aplicación wxPython?

Idealmente, me gustaría capturar todos los resultados (no solo los errores) y registrarlo en un archivo. Las excepciones no controladas deben registrarse en el archivo actual y luego permitir que la excepción se transmita como siempre (es decir, el proceso de registro debe ser transparente).

Estoy seguro de que alguien debe haber hecho algo en esta línea antes, pero no he logrado encontrar nada que se vea útil a través de Google.

Respuesta

6

para el registro de salida estándar, puede utilizar un envoltorio de salida estándar, como este:

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) 

A continuación, tiene que inicializar en su archivo principal de Python (el que controla todo):

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

En cuanto a las excepciones de registro, lo más fácil es ajustar el método MainLoop de wx.App en un intento ... excepto, luego extraiga la información de excepción, guárdela de alguna manera y luego vuelva a subir la excepción a través de raise, p. Ej .:

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

Cheers Dzinx - Terminé usando una combinación de su sugerencia y –

+3

de monopocalypse Intenté hacer esto en mi aplicación para detectar excepciones y mostrar diálogos de error amigables, pero no funcionó. Parece que porque wxPython genera un hilo diferente para App.MainLoop() que las excepciones están fuera del alcance del bloque try/except en ese punto. – Soviut

1

Existen varias formas. Sin embargo, puede poner un bloque try..catch en wxApplication :: OnInit, que no siempre funcionaría con Gtk.

Una buena alternativa sería la de reemplazar la aplicación :: handleEvent en su clase wxApplication derivada, y escribir un código como este:

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 un C++ ejemplo, pero seguramente se puede traducir a Python fácilmente.

9

Para el manejo de excepciones, asumiendo que su archivo de registro se abre como log:

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 
+0

Cheers monopocalypse: terminé usando una combinación de tu sugerencia y la de Dzinx. ¡Ojalá pudiera aceptar tus dos respuestas! –

3

Puede utilizar

sys.excepthook

(ver Python docs)

y asigne algún objeto personalizado, que capturaría todas las excepciones no detectadas anteriormente en su código. A continuación, puede registrar cualquier mensaje en cualquier archivo que desee, junto con el rastreo y hacer lo que quiera con la excepción (resérvelo, muestre un mensaje de error y permita que el usuario continúe usando su aplicación, etc.).

En cuanto a log stdout, la mejor manera para mí fue escribir algo similar a OutWrapper de DzinX.

Si se encuentra en la etapa de depuración, considere vaciar sus archivos de registro después de cada entrada. Esto perjudica mucho el rendimiento, pero si logras causar segfault en algún código C subyacente, tus registros no te inducirán a error.

Cuestiones relacionadas