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. P>
Comment puis-je faire cela? P>
5 Réponses :
try:
# blah blah The Main Loop, function, whatever...
except e:
do_something_with(str(e))
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
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
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 .
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., Réponse: Construire une cachette d'urgence pour que vous sachiez que vous pouvez le dépenser dans de telles urgences: p> 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?
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()