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