21
$ ./runtests.py -v tests/managers/test_customer.py:CustomerManagerTest.test_register_without_subscription --ipdb

...

test_register_without_subscription (tests.managers.test_customer.CustomerManagerTest) ... 
- TRACEBACK --------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/unittest/case.py", line 331, in run
    testMethod()
  File "*****/tests/managers/test_customer.py", line 198, in test_register_without_subscription
    1/0
ZeroDivisionError: integer division or modulo by zero
--------------------------------------------------------------------------------
> *****/tests/managers/test_customer.py(198)test_register_without_subscription()
    197     def test_register_without_subscription(self):
--> 198         1/0
    199         ...

ipdb> import sys
ipdb> sys.exc_info()
(<type 'exceptions.AttributeError'>, AttributeError("Pdb instance has no attribute 'do_sys'",), <traceback object at 0x47eb908>)
ipdb> 

I could not find any command in ipdb help that shows me current exception.

Doing import sys; print sys.exc_info() doesn't work.

Currently I do:

try:
    do_something_that_raises_an_exception()
except Exception as exc:
    import ipdb; ipdb.set_trace()

then I can work with exc to analyze it.

How to easily get a reference to the currently effective exception?

shx2
  • 61,779
  • 13
  • 130
  • 153
warvariuc
  • 57,116
  • 41
  • 173
  • 227
  • Looks like this may have already been answered here: http://stackoverflow.com/a/19211195/399704 – Aaron D Apr 09 '14 at 20:34
  • @AaronD, the answer in your link only works in `pdb`, not `ipdb`... – shx2 Apr 09 '14 at 20:41
  • @AaronD, i am getting `AttributeError: 'module' object has no attribute 'last_value'` when trying to retrieve `sys.last_value` inside an `except`: http://bugs.python.org/issue6307 – warvariuc Apr 10 '14 at 05:03

1 Answers1

42

This has frustrated me too for a while. I eventually found the answer here, along with a good detailed explanation.

The short answer is, use the ! magic prefix (!sys.exc_info()):

In [4]: 1/0
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
...
ipdb> !sys.exc_info()
(<type 'exceptions.AttributeError'>, AttributeError("'exceptions.ZeroDivisionError' object has no attribute '_render_traceback_'",), <traceback object at 0x101c55fc8>)

This basically tells the debugger: "guessing wouldn't be necessary. it is python code I'm typing", thus preventing it from trying to guess what you mean by "sys", a process during which some internal exception is raised, overwriting sys.exc_info(), which used to hold your original exception.

augustomen
  • 8,977
  • 3
  • 43
  • 63
shx2
  • 61,779
  • 13
  • 130
  • 153
  • 2
    Thanks, this works. I was hoping there is a built-in `ipdb` command for this, otherwise I have to type: `!import sys; sys.exc_info()` – warvariuc Apr 10 '14 at 05:03
  • @warwaruk you can define an alias in your `.pdbrc` – shx2 Apr 10 '14 at 05:18
  • 6
    Thanks! I ended up with putting `alias exc_info !import sys; sys.exc_info()` into `~/.pdbrc` – warvariuc Apr 10 '14 at 05:43
  • 2
    This works in both pdb & ipdb. To assign to a variable, you can use `!import sys; exc=sys.exc_info()` then you can explore it, import `traceback` and print it, etc. – rcoup Aug 02 '16 at 20:42
  • 1
    Very helpful!. FYI, The link for where you got the idea no longer leads to anything relevant. – Scott H Jun 15 '18 at 14:14