How to get inner exception traceback

Discussion in 'Python' started by Thomas Guettler, Apr 24, 2008.

  1. Hi,

    How can you get the traceback of the inner exception?

    try:
    try:
    import does_not_exit
    except ImportError:
    raise Exception("something wrong")
    except:
    ...


    Background: In Django some exceptions are caught and a new
    exception gets raised. Unfortunately the real error is hard
    to find. Sometimes I help myself and change (in this example)
    ImportError to e.g. IOError and then I can see the real root
    of the problem. But maybe there is a way to get the inner
    exception and its traceback. This could be displayed in the
    debug view.

    Thomas

    --
    Thomas Guettler, http://www.thomas-guettler.de/
    E-Mail: guettli (*) thomas-guettler + de
     
    Thomas Guettler, Apr 24, 2008
    #1
    1. Advertising

  2. Thomas Guettler

    Peter Otten Guest

    Thomas Guettler wrote:

    > How can you get the traceback of the inner exception?


    You have to record it yourself or it will be lost.

    > try:
    > try:
    > import does_not_exit
    > except ImportError:
    > raise Exception("something wrong")
    > except:
    > ...
    >
    >
    > Background: In Django some exceptions are caught and a new
    > exception gets raised. Unfortunately the real error is hard
    > to find. Sometimes I help myself and change (in this example)
    > ImportError to e.g. IOError and then I can see the real root
    > of the problem. But maybe there is a way to get the inner
    > exception and its traceback. This could be displayed in the
    > debug view.


    You can get the current exception and traceback with

    sys.exc_info()

    and later print or format it using the traceback module.

    >>> try:

    .... 1/0
    .... except Exception:
    .... x = sys.exc_info()
    .... raise ValueError
    ....
    Traceback (most recent call last):
    File "<stdin>", line 5, in <module>
    ValueError
    >>> traceback.print_exception(*x)

    Traceback (most recent call last):
    File "<stdin>", line 2, in <module>
    ZeroDivisionError: integer division or modulo by zero

    Peter
     
    Peter Otten, Apr 24, 2008
    #2
    1. Advertising

  3. Thomas Guettler

    Guest

    On 24 Apr, 13:20, Thomas Guettler <> wrote:
    > Hi,
    >
    > How can you get the traceback of the inner exception?
    >
    > try:
    >      try:
    >          import does_not_exit
    >      except ImportError:
    >          raise Exception("something wrong")
    > except:
    >      ...
    >
    > Background: In Django some exceptions are caught and a new
    > exception gets raised. Unfortunately the real error is hard
    > to find. Sometimes I help myself and change (in this example)
    > ImportError to e.g. IOError and then I can see the real root
    > of the problem. But maybe there is a way to get the inner
    > exception and its traceback. This could be displayed in the
    > debug view.
    >
    >   Thomas
    >
    > --
    > Thomas Guettler,http://www.thomas-guettler.de/
    > E-Mail: guettli (*) thomas-guettler + de


    I'm not sure it ill work since sys.exc_info() might not return a deep
    copy of the traceback info,
    but you could try to store the inner exception and its traceback as
    attributes of the outer exception:

    class ReraisedException(Exception):
    def __init__(self, message, exc_info):
    Exception.__init__(self, message)
    self.inner_exception = exc_info

    try:
    try:
    import does_not_exit
    except ImportError:
    raise ReraisedException("Something wrong", sys.exc_info() )
    except ReraisedException, e:
    ... # here you can use e.inner_exception
    except:
    ...


    Ciao
    -----
    FB
     
    , Apr 24, 2008
    #3
  4. schrieb:
    > On 24 Apr, 13:20, Thomas Guettler <> wrote:
    >> Hi,
    >>
    >> How can you get the traceback of the inner exception?
    >>
    >> try:
    >> try:
    >> import does_not_exit
    >> except ImportError:
    >> raise Exception("something wrong")
    >> except:
    >> ...
    >>
    >> Background: In Django some exceptions are caught and a new
    >> exception gets raised. Unfortunately the real error is hard
    >> to find. Sometimes I help myself and change (in this example)
    >> ImportError to e.g. IOError and then I can see the real root
    >> of the problem. But maybe there is a way to get the inner
    >> exception and its traceback. This could be displayed in the
    >> debug view.
    >>
    >> Thomas
    >>
    >> --
    >> Thomas Guettler,http://www.thomas-guettler.de/
    >> E-Mail: guettli (*) thomas-guettler + de

    >
    > I'm not sure it ill work since sys.exc_info() might not return a deep
    > copy of the traceback info,
    > but you could try to store the inner exception and its traceback as
    > attributes of the outer exception:
    >
    > class ReraisedException(Exception):
    > def __init__(self, message, exc_info):
    > Exception.__init__(self, message)
    > self.inner_exception = exc_info
    >
    > try:
    > try:
    > import does_not_exit
    > except ImportError:
    > raise ReraisedException("Something wrong", sys.exc_info() )
    > except ReraisedException, e:
    > ... # here you can use e.inner_exception
    > except:


    This may lead to reference cycles, please read
    http://docs.python.org/dev/library/sys.html#sys.exc_info

    Christian
     
    Christian Heimes, Apr 24, 2008
    #4
  5. Thomas Guettler

    Guest

    On 24 Apr, 15:00, Christian Heimes <> wrote:
    > schrieb:
    >

    :
    >
    > > class ReraisedException(Exception):
    > >     def __init__(self, message, exc_info):
    > >         Exception.__init__(self, message)
    > >         self.inner_exception = exc_info

    >
    > >  try:
    > >       try:
    > >           import does_not_exit
    > >       except ImportError:
    > >            raise ReraisedException("Something wrong", sys.exc_info() )
    > >  except ReraisedException, e:
    > >      ... # here you can use e.inner_exception
    > >  except:

    >
    > This may lead to reference cycles, please readhttp://docs.python.org/dev/library/sys.html#sys.exc_info
    >
    > Christian- Nascondi testo tra virgolette -
    >
    > - Mostra testo tra virgolette -


    Thanks. I was not aware of that (Last time I read that section, the
    warning was not there).
    I usually do something like that in my scripts:

    try:
    do_something()
    except:
    err, detail, tb = sys.exc_info()
    print err, detail
    traceback.print_tb(tb)

    According to the document you linked to, also this causes circular
    reference, although in my case
    it is ininfluent , since I usually do it only before exiting a program
    after a
    fatal error.

    However, this seems like a dark spot in the implementation of
    CPython.
    Do you now if this has/will be cleaned in Python 3.x ? I'd like to
    see a 'print_tb'
    method in the exception class, so that I could do something like this:

    try:
    do_something()
    except Exception, e : # I know, in python 3.0 the syntax will be
    different
    print e
    e.print_tb()


    Ciao
    -------
    F.B.
     
    , Apr 24, 2008
    #5
  6. En Thu, 24 Apr 2008 08:20:29 -0300, Thomas Guettler <>
    escribió:

    > How can you get the traceback of the inner exception?
    >
    > try:
    > try:
    > import does_not_exit
    > except ImportError:
    > raise Exception("something wrong")
    > except:
    > ...
    >
    >
    > Background: In Django some exceptions are caught and a new
    > exception gets raised. Unfortunately the real error is hard
    > to find. Sometimes I help myself and change (in this example)
    > ImportError to e.g. IOError and then I can see the real root
    > of the problem. But maybe there is a way to get the inner
    > exception and its traceback. This could be displayed in the
    > debug view.


    You already got a couple ways to do it - but I'd ask why do you want to
    mask the original exception? If you don't have anything valuable to do
    with it, just don't catch it. Or raise the *same* exception+context,
    perhaps after modifying it a bit:

    try:
    try:
    import does_not_exist
    except ImportError, e:
    e.args = ("Something is wrong with the plugin system\nDetails: %s" %
    e.args,)
    raise # <-- note the "bare" raise
    except:
    import traceback
    print "An error has occurred"
    print sys.exc_info()[1]
    print sys.exc_info()[0].__name__
    traceback.print_tb(sys.exc_info()[2])
    # or whatever you want to do with the exception

    --
    Gabriel Genellina
     
    Gabriel Genellina, Apr 25, 2008
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Carlo v. Dango
    Replies:
    14
    Views:
    1,103
    Alex Martelli
    Oct 19, 2003
  2. Jan Decaluwe
    Replies:
    0
    Views:
    325
    Jan Decaluwe
    Nov 7, 2003
  3. Joe Peterson
    Replies:
    4
    Views:
    317
    Joe Peterson
    Jul 5, 2005
  4. Pyenos
    Replies:
    2
    Views:
    415
    Pyenos
    Dec 27, 2006
  5. Jack Bates
    Replies:
    0
    Views:
    295
    Jack Bates
    May 2, 2011
Loading...

Share This Page