|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /usr/lib64/python2.4/site-packages/rhpl/ |
Upload File : |
#!/usr/bin/python
# -*- coding: utf-8 -*-
## Copyright (C) 2001-2005 Red Hat, Inc.
## Copyright (C) 2001-2005 Harald Hoyer <harald@redhat.com>
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
"""Module for a userfriendly exception handling
Example code:
import sys
from rhpl.exception import action, error, exitcode, installExceptionHandler
installExceptionHandler("test", "1.0", gui=0, debug=0)
def exception_function():
action("Trying to divide by zero")
try:
local_var_1 = 1
local_var_2 = 0
# test exception raised to show the effect
local_var_3 = local_var_1 / local_var_2
except:
error("Does not seem to work!? :-)")
exitcode(15)
raise
if __name__ == '__main__':
exception_function()
sys.exit(0)
"""
import os, sys
from rhpl.translate import _
#
# __ExceptionWindow class
#
class __ExceptionWindow:
def __init__ (self, text, component_name):
import gtk
win = gtk.Dialog(_("Exception Occurred"), None, gtk.DIALOG_MODAL)
win.add_button(_("_Debug"), 0)
win.add_button(_("_Save to file"), 1)
win.add_button(gtk.STOCK_QUIT, 2)
win.set_border_width(6)
buffer = gtk.TextBuffer(None)
buffer.set_text(text)
textbox = gtk.TextView()
textbox.set_buffer(buffer)
textbox.set_property("editable", False)
textbox.set_property("cursor_visible", False)
sw = gtk.ScrolledWindow ()
sw.set_shadow_type(gtk.SHADOW_IN)
sw.add (textbox)
sw.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
hbox = gtk.HBox (False)
hbox.set_border_width(6)
txt = _("An unhandled exception has occurred. This "
"is most likely a bug. Please save the crash "
"dump and file a detailed bug "
"report against %s at "
"https://bugzilla.redhat.com/bugzilla") % \
component_name
info = gtk.Label(txt)
info.set_line_wrap(True)
hbox.pack_start (sw, True)
win.vbox.pack_start (info, False)
win.vbox.pack_start (hbox, True)
win.vbox.set_border_width(12)
win.vbox.set_spacing(12)
win.set_size_request (500, 300)
win.set_position (gtk.WIN_POS_CENTER)
contents = win.get_children()[0]
win.show_all ()
self.window = win
self.rc = self.window.run ()
self.window.destroy()
def quit (self, dialog, button):
self.rc = button
def getrc (self):
# I did it this way for future expantion
# 0 is debug
if self.rc == 0:
return 1
# 1 is save
if self.rc == 1:
return 2
# 2 is OK
elif self.rc == 2:
return 0
__dumpHash = {}
# XXX do length limits on obj dumps.
def __dumpClass(instance, fd, level=0):
import types
global __dumpHash
# protect from loops
if not __dumpHash.has_key(instance):
__dumpHash[instance] = None
else:
fd.write("Already dumped\n")
return
if (instance.__class__.__dict__.has_key("__str__") or
instance.__class__.__dict__.has_key("__repr__")):
fd.write("%s\n" % (instance,))
return
fd.write("%s instance, containing members:\n" %
(instance.__class__.__name__))
pad = ' ' * ((level) * 2)
for key, value in instance.__dict__.items():
if type(value) == types.ListType:
fd.write("%s%s: [" % (pad, key))
first = 1
for item in value:
if not first:
fd.write(", ")
else:
first = 0
if type(item) == types.InstanceType:
__dumpClass(item, fd, level + 1)
else:
fd.write("%s" % (item,))
fd.write("]\n")
elif type(value) == types.DictType:
fd.write("%s%s: {" % (pad, key))
first = 1
for k, v in value.items():
if not first:
fd.write(", ")
else:
first = 0
if type(k) == types.StringType:
fd.write("'%s': " % (k,))
else:
fd.write("%s: " % (k,))
if type(v) == types.InstanceType:
__dumpClass(v, fd, level + 1)
else:
fd.write("%s" % (v,))
fd.write("}\n")
elif type(value) == types.InstanceType:
fd.write("%s%s: " % (pad, key))
__dumpClass(value, fd, level + 1)
else:
fd.write("%s%s: %s\n" % (pad, key, value))
def __dumpException(out, text, tb):
from cPickle import Pickler
p = Pickler(out)
out.write(text)
trace = tb
while trace.tb_next:
trace = trace.tb_next
frame = trace.tb_frame
out.write ("\nLocal variables in innermost frame:\n")
try:
for (key, value) in frame.f_locals.items():
out.write ("%s: %s\n" % (key, value))
except:
pass
def __exceptionWindow(title, text, name):
import gtk
#print text
win = __ExceptionWindow (text, name)
return win.getrc ()
def __generic_error_dialog (message, parent_dialog,
message_type=None,
widget=None, page=0, broken_widget=None):
import gtk
if message_type == None:
message_type = gtk.MESSAGE_ERROR
dialog = gtk.MessageDialog(parent_dialog,
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
message_type, gtk.BUTTONS_OK,
message)
if widget != None:
if isinstance (widget, gtk.CList):
widget.select_row (page, 0)
elif isinstance (widget, gtk.Notebook):
widget.set_current_page (page)
if broken_widget != None:
broken_widget.grab_focus ()
if isinstance (broken_widget, gtk.Entry):
broken_widget.select_region (0, -1)
if parent_dialog:
dialog.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
dialog.set_transient_for(parent_dialog)
else:
dialog.set_position (gtk.WIN_POS_CENTER)
ret = dialog.run ()
dialog.destroy()
return ret
__action_str = ""
def action(what):
"""Describe what you want to do actually.
what - string
"""
global __action_str
__action_str = what
__error_str = ""
def error(what):
"""Describe what went wrong with a userfriendly text.
what - string
"""
global __error_str
__error_str = what
__exitcode = 10
def exitcode(num):
"""The exitcode, with which the exception handling routine should call
sys.exit().
num - int(exitcode)
"""
global __exitcode
__exitcode = int(num)
def installExceptionHandler(progname, version, gui = 1, debug = 1):
"""
Install the exception handling function.
progname - the name of the application
version - the version of the application
gui - display a gtk dialog (0,1) to show the error message
debug - show the full traceback (with "Save to file" in GUI)
"""
sys.excepthook = lambda type, value, tb: handleException((type, value, tb), progname, version, gui, debug)
#
# handleException function
#
def handleException((type, value, tb), progname, version, gui = 1, debug = 1):
"""
The exception handling function.
progname - the name of the application
version - the version of the application
gui - display a gtk dialog (0,1) to show the error message
debug - show the full traceback (with "Save to file" in GUI)
"""
global __action_str
global __error_str
global __exitcode
if not debug:
if not gui:
print _("Error: %s: %s") % (__action_str, __error_str)
else:
import gtk
text = _("%s\n\n%s:\n%s") % (progname, __action_str, __error_str)
__generic_error_dialog(text, None)
sys.exit(__exitcode)
# restore original exception handler
sys.excepthook = sys.__excepthook__
import os.path
import md5
from string import joinfields
import traceback
list = traceback.format_exception (type, value, tb)
tblast = traceback.extract_tb(tb, limit=None)
if len(tblast):
tblast = tblast[len(tblast)-1]
extxt = traceback.format_exception_only(type, value)
if progname:
text = "Component: %s\n" % progname
if version:
text = text + "Version: %s\n" % version
text = text + "Summary: TB"
if tblast and len(tblast) > 3:
ll = []
ll.extend(tblast[:3])
ll[0] = os.path.basename(tblast[0])
tblast = ll
m = md5.new()
ntext = ""
for t in tblast:
ntext += str(t) + ":"
m.update(str(t))
text += str(m.hexdigest())[:8] + " " + ntext
text += extxt[0]
text += "\n"
text += joinfields(list, "")
trace = tb
while trace.tb_next:
trace = trace.tb_next
frame = trace.tb_frame
text += ("\nLocal variables in innermost frame:\n")
try:
for (key, value) in frame.f_locals.items():
text += "%s: %s\n" % (key, value)
except:
pass
if not gui:
print text
sys.exit(__exitcode)
import gtk
if not debug:
__generic_error_dialog(text, None)
sys.exit(__exitcode)
while 1:
rc = __exceptionWindow (_("Exception Occurred"), text, progname)
print text
if rc == 1 and tb:
import pdb
import signal
pdb.post_mortem (tb)
os.kill(os.getpid(), signal.SIGKILL)
elif not rc:
sys.exit(__exitcode)
else:
d = gtk.FileChooserDialog(_("Specify a file to save the dump"),
None, gtk.FILE_CHOOSER_ACTION_SAVE,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN, gtk.RESPONSE_OK))
d.set_default_response(gtk.RESPONSE_OK)
rc = d.run()
if rc == gtk.RESPONSE_OK:
file = d.get_filename()
d.destroy()
if not file or file=="":
file = "/tmp/dump"
try:
out = open(file, "w")
out.write(text)
out.close()
except IOError:
__generic_error_dialog(_("Failed to write to file %s.") \
% (file), None)
else:
__generic_error_dialog(
_("The application's state has been successfully\n"
"written to the file '%s'.") % (file), None,
message_type = "info")
sys.exit(__exitcode)
else:
d.destroy()
continue
sys.exit(__exitcode)
if __name__ == '__main__':
def __exception_function():
action("Trying to divide by zero")
try:
local_var_1 = 1
local_var_2 = 0
# test exception raised to show the effect
local_var_3 = local_var_1 / local_var_2
except:
error("Does not seem to work!? :-)")
exitcode(15)
raise
def __usage():
print """%s [-dgh] [--debug] [--gui] [--help]
-d, --debug
Show the whole backtrace
-g, --gui
Display a gtk error dialog
-h, --help
Display this message""" % (sys.argv[0])
import sys
import getopt
debug = 1
gui = 0
installExceptionHandler("test", "1.0", gui, debug)
debug = 0
class BadUsage: pass
try:
opts, args = getopt.getopt(sys.argv[1:], "dgh",
[
"debug",
"help",
"gui",
])
for opt, val in opts:
if opt == '-d' or opt == '--debug':
debug = 1
continue
if opt == '-g' or opt == '--gui':
gui = 1
continue
if opt == '-h' or opt == '--help':
__usage()
sys.exit(0)
except (getopt.error, BadUsage):
__usage()
sys.exit(1)
installExceptionHandler("test", "1.0", gui, debug)
__exception_function()
sys.exit(0)
__author__ = "Harald Hoyer <harald@redhat.com>"