Pregunta

Estoy escribiendo una pequeña aplicación de depuración para un pequeño kit que estamos desarrollando y me gustaría extenderlo a algunos usuarios para ver si pueden provocar algún fallo. ¿Alguien sabe una manera de envolver efectivamente una aplicación wxPython para detectar todas las excepciones no controladas que podrían hacer que la aplicación se bloquee?

Idealmente, me gustaría capturar toda la salida (no solo los errores) y registrarla en un archivo. Cualquier excepción no controlada debe iniciar sesión en el archivo actual y luego permitir que la excepción se transmita como de costumbre (es decir, el proceso de registro debe ser transparente).

Estoy seguro de que alguien debe haber hecho algo como esta antes, pero no he podido encontrar nada que parezca útil a través de google.

¿Fue útil?

Solución

Para el registro de salida estándar, puede usar un envoltorio stdout, 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)

Luego debes inicializarlo en tu archivo principal de Python (el que lo ejecuta todo):

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

En cuanto al registro de excepciones, lo más fácil es envolver el método MainLoop de wx.App en un try..except, luego extraer la información de la excepción, guardarla de alguna manera y luego vuelva a elevar la excepción a través de raise , por ejemplo:

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

Otros consejos

Para el manejo de excepciones, asumiendo que su archivo de registro se abre como 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

Puedes usar

  

sys.excepthook

(consulte documentos de Python )

y asignarle algún objeto personalizado, que detectaría todas las excepciones no detectadas anteriormente en su código. Luego puede registrar cualquier mensaje en el archivo que desee, junto con el rastreo y hacer lo que quiera con la excepción (volver a generarlo, mostrar un mensaje de error y permitir que el usuario continúe usando su aplicación, etc.).

En cuanto al inicio de sesión estándar, la mejor manera para mí era escribir algo similar al OutWrapper de DzinX.

Si está en la etapa de depuración, considere vaciar los archivos de registro después de cada entrada. Esto perjudica mucho el rendimiento, pero si logra causar un defecto en algún código C subyacente, sus registros no lo engañarán.

Hay varias maneras. Puede poner un bloque try..catch en wxApplication :: OnInit, sin embargo, eso no siempre funcionaría con Gtk.

Una buena alternativa sería anular Application :: HandleEvent en su clase derivada de wxApplication 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 ejemplo de C ++, pero seguramente puedes traducirlo a Python fácilmente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top