10
votes

Python: Comment puis-je gérer toute exception non gérée de manière alternative?

Les exceptions normalement non gênées vont au stdout (ou stardr?), je construisais une application où je veux transmettre ces informations à l'interface graphique avant d'arrêter et d'l'afficher à l'utilisateur et, en même temps, je veux écrire à un fichier journal. Donc, j'ai besoin d'un STR avec le texte intégral de l'exception.

Comment puis-je faire cela?


0 commentaires

5 Réponses :


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

0 commentaires

1
votes
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

0 commentaires

21
votes

Utilisez SYS.EXCEPTHOOK pour remplacer le gestionnaire d'exception de base. Vous pouvez faire quelque chose comme:

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


1 commentaires

Il met en cache toutes les exceptions non manquées dans le fil principal, mais si vous utilisez le module de threading, le filetage. Thread a son propre manuel / sauf le gestionnaire qui contourne Sys.excepthook. Voir BOGS.PLYTHON.ORG/issue1230540 .



10
votes

Vous avez déjà d'excellentes réponses, je voulais juste ajouter un conseil de plus qui m'a bien servi au fil des ans dans une variété de langage pour le problème spécifique "Comment diagnostiquer de manière proprement, journal, etc., hors de mémoire < / code> erreurs? ". Le problème est que si votre code obtient le contrôle avant que suffisamment d'objets a été détruit et que leur mémoire recyclée, la mémoire pourrait être trop serrée pour faire une exploitation de la propriété, une interface graphique, etc. Comment cela ne se produit pas?

Réponse: Construire une cachette d'urgence pour que vous sachiez que vous pouvez le dépenser dans de telles urgences: xxx


0 commentaires

1
votes

J'ai essayé d'utiliser réponse de Neil , mais cela ne fonctionne pas avec une interface graphique Tkinter. Pour cela, j'ai dû remplacement repor_callback_exception () code> .

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()


0 commentaires