Reputation: 9637
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?
Upvotes: 32
Views: 16452
Reputation: 2035
You can use:
import sys
sys.exc_info()
In VSCode, type the import in the bottom debug bar.
Upvotes: 1
Reputation: 34324
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.
Upvotes: 30
Reputation: 22818
The python debugger doesn't "break on exception" - which can be quite frustrating if you're used to that functionality. As such, I adopt a policy of logging strack traces and working back from there.
import logging
try:
raise Exception('An exception message with valuable information.')
except:
logging.exception('Error in test code')
If you use a good IDE (such as Eclipse with pydev), the log entries for the stacktrace are made into hyperlinks that jump straight to the appropriate position in code.
You can dump a stack trace at any point in your code by importing traceback
import traceback
trace = traceback.format_exc()
Upvotes: 8