traceback manipulation
cmkl
cmkleffner at gmx.de
Tue Dec 10 08:35:12 EST 2002
hansgeunsmeyer at earthlink.net (hg) wrote in message news:<95959723.0212081925.169ca2d5 at posting.google.com>...
> > If a exception occours, the daemon catches it and the client it
> > re-raising it. However in the traceback on the client I only see the
> > line in the client code, that re-raises the exception
> > ( exec "raise %s, '%s'" % (type, string) )
> > However I'd like to replace the traceback with the server's one...
> >
> > Any ideas?
>
> When an exception occurs you could perhaps return sys.exc_info().
> Then, in the client, you could -- for instance -- check if you got a
> triple (tp, val, tb) back with an Exception as first element, and if
> so, you could try to call traceback.print_exception(tp, val, tb, None,
> None). (This doesn't exactly re-raise the exception, but it does give
> you the original traceback.)
>
> Hans
Hi,
this one works for me (i it got from somewhere in the net and
hacked it to my needs):
this module produces a readable (multiline) string containing
the full traceback/ or the error.
Catch your exception in the daemon and send back the result.
You would get something like that with the test errors in __main__:
don't do that: print 1/0
ZeroDivisionError in:
geterror.py:95 (in function __main__): <<<integer division or modulo
by zero>>>
--> print 1/0
you can't add a string to a number: print 1 + '1'
TypeError: geterror.py:101 (in function __main__): <<<unsupported
operand types for +: 'int' and 'str'>>>
#!/bin/env python
"""traceback/error of a catched exception in readable form.
If PYTHONTRACEBACK is set in enviroment print on stderr also.
Use it within except clause:
from geterror import gettraceback, geterror
try:
print 1/0
except:
print gettraceback()
"""
from traceback import extract_tb
from sys import exc_info, stderr
import os
def gettraceback():
"""Return multiline string with traceback in readable form.
This should be called from inside an except clause only."""
s_err = None
try:
extype, value, tb = exc_info()
info = extract_tb(tb)
value = (value and (": <<<%s>>>" % value) ) or ""
try: # Class Exception
s_err = extype.__name__
except AttributeError: # String Exception
s_err = ( extype and extype ) or "Error"
s_err = "\n%s in:\n\n" % s_err
for i in range(len(info)):
filename, lineno, function, text = info[i]
filename = os.path.basename(filename)
if function == "?": function = "__main__"
s_err += "%s:%d (in function %s)%s%s\n" % (
filename, lineno, function,
( (i == len(info)-1) and value ) or ":",
( text and ("\n --> " + text) ) or ""
)
finally: # avoid circular references: see Dokumenation for
exc_info()
del extype, value, tb, info, filename, lineno, function, text
if os.environ.has_key('PYTHONTRACEBACK'): print >> stderr , s_err
return s_err
def geterror():
"""Return error string in readable form.
This should be called from inside an except clause only."""
s_err = None
try:
extype, value, tb = exc_info()
info = extract_tb(tb)
value = (value and (": <<<%s>>>" % value) ) or ""
try: # Class Exception
s_err = "%s: " % extype.__name__
except AttributeError: # String Exception
s_err = ( extype and extype+": " ) or "Error: "
filename, lineno, function, text = info[-1]
filename = os.path.basename(filename)
if function == "?": function = "__main__"
s_err += "%s:%d (in function %s)%s" % (
filename, lineno, function, value)
finally: # avoid circular references: see Dokumenation for
exc_info()
del extype, value, tb, info, filename, lineno, function, text
if os.environ.has_key('PYTHONTRACEBACK'): print >> stderr , s_err
return s_err
if __name__ == '__main__':
"""Test gettraceback() and geterror()"""
print "\ndon't do that: print 1/0"
try:
print 1/0
except:
print gettraceback()
print "you can't add a string to a number: print 1 + '1'\n"
try:
print 1 + "1"
except:
print geterror()
print
More information about the Python-list
mailing list