preserve exception within try .. finally

B

Brian Alexander

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()

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?


Many thanks,

Brian.
 
A

Alvaro Figueiredo

Em Sex 10 Out 2003 16:57, Brian Alexander escreveu:
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()

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?


Many thanks,

Brian.

I would do:

getResource()
try:
doSomething()
finally:
freeResource()

The exception keeps propagating until it is handled by a try:
except: statement.
 
G

Gonçalo Rodrigues

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()

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?

Maybe I'm not understanding your question but the finally block does
*not* handle the exception. The exception propagates:
.... raise Exception
.... finally:
.... print "I warned you"
....
I warned you
Traceback (most recent call last):

HTH,
G. Rodrigues
 
P

Peter Otten

Brian said:
I'm curious to know how people preserve exceptions that arise in a try
.. finally block. Consider this example:

try:
getResource()
doSomething()
finally:
alwaysFreeResource()

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?

The exception raised by doSomething() travels all the way up the call stack
until it hits an except clause that can catch it, i. e.

except ExceptionRaised:
# handle it

or

except SuperClassOfExceptionRaised:
# handle it

All the finally blocks that lie on the way up are executed.
Note that the correct use of try... finally is

getResource() # don't free if it cannot be acquired
try:
doSomething()
finally
freeResource()

This will typically be included (not necessarily in the same function) by a
try ... except

try:
getResource()
try:
doSomething()
finally
freeResource()
except SomeException, e:
if canHandleIt(e):
#handle it
else:
raise # hope for another handler

I think that the canHandleIt(e) test and the reraising is not very common,
but I included it as you were asking for "keeping it raised", which might
translate into "reraising it".

Peter
 
S

Stephen Horne

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 :
.... 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' ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top