SoFunction
Updated on 2024-10-28

Talking about exception nesting in python

In Python, exceptions can also be nested, when an exception occurs in the inner code, the specified exception type does not match the actual type, it goes outward, and if it matches the specified type outside, the exception is handled up to the outermost level, where it is handled by applying the default handler, i.e., stopping the program and throwing an exception message. The following code:

try:
 try:
  raise IndexError
 except TypeError:
  print('get handled')
except SyntaxError:
 print('ok')

Run the program:

Traceback (most recent call last):
File "<pyshell#47>", line 3, in <module>
raise IndexError
IndexError


Look at another example caught by the outer try-except:

try:
 try:
  1/0
 finally:
  print('finally')
except:
 print('ok')

Running:

finally
ok

It's worth noting here that except: catches all exceptions, but in practice this has the disadvantage of sometimes wrapping scheduled exceptions.


Another thing that needs to be mentioned is RAISE A FROM B, which associates an exception with another exception, so that if the B following the FROM is not caught by the outer layer, then both the A and B exceptions will be thrown, for example:

try:
 1/0
except Exception as E:
 raise TypeError('bad') from E

Running:

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

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "<pyshell#4>", line 4, in <module>
raise TypeError('bad') from E
TypeError: bad

Conversely, if the outer layer captures B:

try:
 try:
  1/0
 except Exception as E:
  raise TypeError from E
except TypeError:
 print('no'

Running:

no


Finally, take a look at how try-finally behaves in nesting.

try:
 try:
  1/0
 finally:
  print('finally')
except:
 print('ok')

Running:

finally
ok

Regardless of whether an exception occurs or not, or whether it is handled or not, the finally code executes, stopping if the exception is handled, and if it is not handled, going outward until it is finally not handled, using the default method of handling, in the above example, the exception is handled at the outermost level.

try:
 try:
  1/0
 except Exception as E:
  print('happens')
 finally:
  print('finally')
except E:
 print('get handled')

Running:

happens
finally

Exceptions are handled internally and are no longer propagated outward.

The above is to talk about the details of exception nesting in python, more information about python exception nesting please pay attention to my other related articles!