Search code examples
pythonexceptiontry-except

What does above exception points to in exception info thrown?


The simplest built-in exception as below:

>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

Throw exception info ,then whole press is done.

Define function f1 and not to define myException:

def f1():
    try:
        print(1/0)
    except:
        raise myException('my exception')

Call f1():

>>> f1()
Traceback (most recent call last):
  File "<stdin>", line 3, in f1
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in f1
NameError: name 'myException' is not defined

When the info

Traceback (most recent call last):
  File "<stdin>", line 3, in f1
ZeroDivisionError: division by zero

thrown out,exception of print(1/0) is handled as we have seen that in the beginning.
Why the statement in the middle line is During handling of the above exception, another exception occurred: ,instead of After handling of the above exception, another exception occurred:?
What is above exception in the statement During handling of the above exception?It points to try ... except structure in f1 ,instead of exception resulted by 1/0?
If above exception points to exception resulted by 1/0,then After handling of the above exception, another exception occurred is better to describe all the exceptions here!


Solution

  • This is exception chaining as described in The raise Statement. You catch the ZeroDivisionError. When you raise MyException, python will automatically add the current exception to its __cause__ attribute.

    That's why you see both exceptions listed. The one you raised, and the one put in the __cause__ attribute. Python lets you customize the exception in several ways, particularly with a "from" exception. Generically, that's

    raise myException from OtherException
    

    More specifically, to fully suppress the original exception and keep it out of the __cause__ attribute, raise from None:

    raise myException from None