2009-08-05 14 views

Respuesta

0
try: 
    # blah blah The Main Loop, function, whatever... 
except e: 
    do_something_with(str(e)) 
+4

supongo que quiere decir "salvo excepción, e:" ... –

2
import sys, logging 

logging.basicConfig(filename='/path/to/log/file', filemode='w')  
... 

try: 
    your_code_here() 
except: 
    logging.exception("My code failed") # logs exception to file 
    # you define display_exception_in_ui as "def display_exception_in_ui(exc, tb):" 
    display_exception_in_ui(*sys.exc_info()[1:]) # passes exception instance, traceback 
15

Uso sys.excepthook para reemplazar el controlador de excepciones de base. Usted puede hacer algo como:

import sys 
from PyQt4 import QtGui 

import os.path 
import traceback 

def handle_exception(exc_type, exc_value, exc_traceback): 
    """ handle all exceptions """ 

    ## KeyboardInterrupt is a special case. 
    ## We don't raise the error dialog when it occurs. 
    if issubclass(exc_type, KeyboardInterrupt): 
    if QtGui.qApp: 
     QtGui.qApp.quit() 
    return 

    filename, line, dummy, dummy = traceback.extract_tb(exc_traceback).pop() 
    filename = os.path.basename(filename) 
    error = "%s: %s" % (exc_type.__name__, exc_value) 

    QtGui.QMessageBox.critical(None,"Error", 
    "<html>A critical error has occured.<br/> " 
    + "<b>%s</b><br/><br/>" % error 
    + "It occurred at <b>line %d</b> of file <b>%s</b>.<br/>" % (line, filename) 
    + "</html>") 

    print "Closed due to an error. This is the full error report:" 
    print 
    print "".join(traceback.format_exception(exc_type, exc_value, exc_traceback)) 
    sys.exit(1) 



# install handler for exceptions 
sys.excepthook = handle_exception 

Esta captura todas las excepciones no controladas, por lo que no necesita un bloque try ... except en el nivel superior de su código.

+2

Se almacena en caché todas las excepciones no controladas en el hilo principal, pero si se utiliza el módulo threading, threading.Thread tiene su propio try/excepto gestor que elude sys.excepthook. Ver http://bugs.python.org/issue1230540. – metamatt

9

Ya recibiste excelentes respuestas, solo quería agregar una sugerencia más que me ha servido durante años en una variedad de idiomas para el problema específico "cómo diagnosticar, registrar, etc., out of memory errores?". El problema es que si su código obtiene control antes de que se destruyan suficientes objetos y se reutilice su memoria, la memoria puede ser demasiado apretada para realizar el registro de propiedades, el trabajo de interfaz gráfica, etc., etc. ¿Cómo nos aseguramos de que esto no ocurra?

Respuesta: construir una reserva de emergencia para que sepa que puede pasar en este tipo de emergencias:

rainydayfund = [[] for x in xrange(16*1024)] # or however much you need 

def handle_exception(e): 
    global rainydayfund 
    del rainydayfund 
    ... etc, etc ... 
0

He intentado utilizar Neil's answer, pero no funciona con una interfaz gráfica de usuario Tkinter. Para eso, tuve que override report_callback_exception().

import Tkinter as tk 
import tkMessageBox 
import traceback 

class MyApp(tk.Frame): 
    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent, *args, **kwargs) 
     parent.report_callback_exception = self.report_callback_exception 
     self.parent = parent 
     self.button_frame = tk.Frame(self) 
     self.button_frame.pack(side='top') 
     self.button_run = tk.Button(
      self.button_frame, text="Run", command=self.run 
     ) 
     self.button_run.grid(row=0, column=1, sticky='W') 

    def run(self): 
     tkMessageBox.showinfo('Info', 'The process is running.') 
     raise RuntimeError('Tripped.') 

    def report_callback_exception(self, exc_type, exc_value, exc_traceback): 
     message = ''.join(traceback.format_exception(exc_type, 
                exc_value, 
                exc_traceback)) 
     tkMessageBox.showerror('Error', message) 

def main(): 
    root = tk.Tk() # parent widget 

    MyApp(root).pack(fill='both', expand=True) 

    root.mainloop() # enter Tk event loop 

if __name__ == '__main__': 
    main() 
Cuestiones relacionadas