[Python-Dev] Handle errors in cleanup code

Serhiy Storchaka storchaka at gmail.com
Mon Jun 12 03:10:28 EDT 2017


There is an idiomatic Python code:

     do_something()
     try:
         do_something_other()
     except:
         undo_something()
         raise

If an error is raised when execute do_something_other(), then we should 
first restore the state that was before calling do_something(), and then 
reraise the exception. It is important that the bare "except" (or 
"except BaseException") is used, because undo_something() should be 
executed on any exception. And this is one of few cases where using the 
bare "except" is correct.

But if an error is raised when execute undo_something(), it replaces the 
original exception which become chaining as the __context__ attribute. 
The problem is that this can change the type of the exception. If 
do_something_other() raises SystemExit and undo_something() raises 
KeyError, the final exception has type KeyError.

Yury in the comment for PR 2108 [1] suggested more complicated code:

     do_something()
     try:
         do_something_other()
     except BaseException as ex:
         try:
             undo_something()
         finally:
             raise ex

Does it mean that we should rewrite every chunk of code similar to the 
above? And if such cumbersome code is necessary and become common, maybe 
it needs syntax support in the language? Or changing the semantic of 
exceptions raised in error handlers and finally blocks?

[1] https://github.com/python/cpython/pull/2108



More information about the Python-Dev mailing list