How can I see the details of an exception in Python's debugger?
Question: Sometimes while I'm debugging an exception will be raised.

For example, consider this code:

    
    
    def some_function():  # Pretend this function is in a library...
        # ...and deep within the library is an exception:
        raise Exception('An exception message with valuable information.')
    
    import pdb; pdb.set_trace()
    try:
        some_function()  # Pretend I am debugging from this point using pdb.
    except:
        pass
    

While debugging from the `some_function()` call, if I issue a `next` command I
will see the following details about the exception that was raised [and
caught]:

    
    
    Exception: Exceptio...ation.',)
    

Here's a straight copy / paste from the terminal I was working in:

    
    
    > /tmp/test.py(7)<module>()
    -> some_function()  # Pretend I am debugging from this point using pdb.
    (Pdb) next
    Exception: Exceptio...ation.',)
    > /tmp/test.py(7)<module>()
    -> some_function()  # Pretend I am debugging from this point using pdb.
    (Pdb) 
    

It would be useful to see the entire exception message. How can I do this in
pdb?


Answer: `pdb` stores the exception type and value in `__exception__`. You can print
the exception part of a traceback in `pdb` with:

    
    
    import traceback; print "".join(traceback.format_exception_only(*__exception__))
    

For example:

    
    
    > /tmp/test.py(7)<module>()
    -> some_function()  # Pretend I am debugging from this point using pdb.
    (Pdb) next
    Exception: Exceptio...ation.',)
    > /tmp/test.py(7)<module>()
    -> some_function()  # Pretend I am debugging from this point using pdb.
    (Pdb) import traceback; print "".join(traceback.format_exception_only(*__exception__))
    Exception: An exception message with valuable information.
    
    (Pdb) 
    

Unfortunately this does not include the rest of the traceback, but all that
information is available through the `where` command of `pdb` anyway. If you
really want the full traceback, you can add the following to your `~/.pdbrc`
file or paste it into your terminal:

    
    
    !global __currentframe, __stack; from inspect import currentframe as __currentframe, stack as __stack
    !global __format_exception_only, __print_stack; from traceback import format_exception_only as __format_exception_only, print_stack as __print_stack
    !global __Pdb; from pdb import Pdb as __Pdb
    
    # find the last frame on the stack with an object named "pdb" or "self" that is a pdb.Pdb object
    # works for pdb called the usual way, or pdb.pm(), or pdb.set_trace()
    !global __pdb; __pdb = [__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self") for __framerec in __stack() if (__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self")).__class__ == __Pdb][-1]
    
    alias traceback __print_stack(__pdb.stack[-1][0]); print "".join(__format_exception_only(*__exception__))
    

Then you can just use the new `traceback` alias to get what you want:

    
    
    > /tmp/test.py(7)<module>()
    -> some_function()  # Pretend I am debugging from this point using pdb.
    (Pdb) next
    Exception: Exceptio...ation.',)
    > /tmp/test.py(7)<module>()
    -> some_function()  # Pretend I am debugging from this point using pdb.
    (Pdb) traceback
      File "test.py", line 7, in <module>
        some_function()  # Pretend I am debugging from this point using pdb.
      File "test.py", line 3, in some_function
        raise Exception('An exception message with valuable information.')
    Exception: An exception message with valuable information.
    
    (Pdb) 
    

Warning: all of this relies on undocumented `pdb` and `bdb` internals and is
likely to break.

