IPython has `%xmode`

magic that adds more context to stack traces.

Here is an example. Let’s create ZeroDivisionError by making nested function calls:

```
def f1(x, y):
z1 = x*y
z2 = x/y + z1
return z2
def f2(a, b):
c1 = a**2
c2 = f1(a, b) + c1
return c2
f2(42, 0)
```

`%xmode plain`

reverts to a really simple, standard Python traceback:

```
Traceback (most recent call last):
File "<ipython-input-175-58764fec4b78>", line 1, in <module>
f2(42, 0)
File "<ipython-input-173-52549b1a98b6>", line 7, in f2
c2 = f1(a, b) + c1
File "<ipython-input-173-52549b1a98b6>", line 3, in f1
z2 = x/y + z1
ZeroDivisionError: division by zero
```

`%xmode context`

(the IPython default) also shows some source context around the lines in the call stack:

```
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-177-58764fec4b78> in <module>()
----> 1 f2(42, 0)
<ipython-input-173-52549b1a98b6> in f2(a, b)
5 def f2(a, b):
6 c1 = a**2
----> 7 c2 = f1(a, b) + c1
8 return c2
<ipython-input-173-52549b1a98b6> in f1(x, y)
1 def f1(x, y):
2 z1 = x*y
----> 3 z2 = x/y + z1
4 return z2
5 def f2(a, b):
ZeroDivisionError: division by zero
```

Finally, `%xmode verbose`

shows context and also values of the variables that are used in evaluation of an exceptionous expression:

```
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-179-58764fec4b78> in <module>()
----> 1 f2(42, 0)
global f2 = <function f2 at 0x7feca605b158>
<ipython-input-173-52549b1a98b6> in f2(a=42, b=0)
5 def f2(a, b):
6 c1 = a**2
----> 7 c2 = f1(a, b) + c1
c2 = undefined
global f1 = <function f1 at 0x7feca60aa510>
a = 42
b = 0
c1 = 1764
8 return c2
<ipython-input-173-52549b1a98b6> in f1(x=42, y=0)
1 def f1(x, y):
2 z1 = x*y
----> 3 z2 = x/y + z1
z2 = undefined
x = 42
y = 0
z1 = 0
4 return z2
5 def f2(a, b):
ZeroDivisionError: division by zero
```

The last mode alleviates the need for debugger in some cases: sometimes, you can locate the error just by looking at the variables’ values in the moment when the exception has occured.