How to access re-raised exception in Python 3?
<p>In Python 3, there's a <a href="https://blog.ionelmc.ro/2014/08/03/the-most-underrated-feature-in-python-3/" rel="nofollow">useful <code>raise ... from ...</code> feature</a> to re-raise an exception. That said, how do you find the original (/ re-raised) exception from the raised exception? Here's a (silly) example with comments to demonstrate what I mean--</p>

<pre><code>def some_func():
    try:
      None() # TypeError: 'NoneType' object is not callable
    except as err:
      raise Exception("blah") from err

try:
    some_func()
except as err:
    # how can I access the original exception (TypeError)?
</code></pre>

<p>Whenever an exception is raised from an exception handler (the <code>except</code> clause), the original exception will bestored in new exception's <code>__context__</code>.</p>

<p>Whenever an exception is raised using <code>from</code> syntax, the exception specified in <code>from</code> will be saved in the <code>__cause__</code> attribute of the new exception.</p>

<p>In the usual use case, that amounts to both <code>__cause__</code> and <code>__context__</code> containing the original exception:</p>

<pre><code>def f():
    try:
        raise Exception('first exception')
    except Exception as e:
        raise Exception('second exception') from e

try:
    f()
except Exception as e:
    print('This exception', e)
    print('Original exception', e.__context__)
    print('Also original exception', e.__cause__)
</code></pre>

<p>Here is also an example of when <code>__context__</code> is set:</p>

<pre><code>try:
    raise Exception('first exception')
except Exception as e:
    raise Exception('second exception')
</code></pre>

<p>and an example of when <code>__cause__</code> is set:</p>

<pre><code>e = Exception('first exception')
raise Exception('second exception') from e
</code></pre>

python python-3.x exception exception-handling