preserve exception within try .. finally

Stephen Horne $$$$$$$$$$$$$$$$$ at $$$$$$$$$$$$$$$$$$$$.co.uk
Sat Oct 11 00:05:36 EDT 2003


On Fri, 10 Oct 2003 15:57:13 -0400, Brian Alexander
<brian094 at sympatico.ca> wrote:

>Hello;
>
>I'm curious to know how people preserve exceptions that arise in a try 
>.. finally block. Consider this example:
>
>try:
>   getResource()
>   doSomething()
>finally:
>   alwaysFreeResource()

I would typically go with...

try:
  getResource()
  doSomething()
  freeResource()

except ResourceAllocationFailed :
  cleanupWithoutFreeResource ()
  raise # re-raise same exception

except :
  cleanupWithoutFreeResource ()
  freeResource ()
  raise # re-raise same exception


The reason being that you don't want to free a resource if you
couldn't allocate it in the first place - cleanup actions often depend
of what exact exception occurred.

However, if you write your cleanup code to handle this, using a
'finally' is normally cleaner.

>If an exception occurs in doSomething(), the resource is freed anyway -- 
>which is good. How can I keep the exception 'raised' for another 
>try-finally/except to deal with? Does this problem reflect an error in 
>the way I am approaching the problem?

I'm pretty sure you don't need to. If the 'finally' block was entered
due to an exception, the exception is automatically reraised at the
end. If the 'finally' block is entered because the 'try' block was
exhausted, no exception is raised. This will normally do what you want
automatically.

For example...

>>> try :
...   try :
...     raise ErrorName
...   finally :
...     print "Finally 1"
...   print "Hello"
... finally :
...   print "Finally 2"
...
Finally 1
Finally 2
Traceback (most recent call last):
  File "<stdin>", line 3, in ?
NameError: name 'ErrorName' is not defined


The "Hello" is not printed because the inner finally block reraises
the exception. The outer finally block does the same, so the exception
propogates all the way out to trigger a traceback. Obviously from the
traceback given, I didn't bother declaring 'ErrorName' ;-)


-- 
Steve Horne

steve at ninereeds dot fsnet dot co dot uk




More information about the Python-list mailing list