Re-raising the right exception

S

SM

try:
x = 1/0
except ZeroDivisionError:
print "caught ZeroDivisionError"
try:
name_error
except NameError:
print "caught NameError"
raise

According to the Python Language Reference
http://docs.python.org/ref/raise.html
'raise' re-raises the last expression that was active in the current
scope. Here apparently "scope" means some sort of lexical scope,
because this program terminates with a NameError exception and not a
ZeroDivisionError.

It seems useful to have a way to raise the exception that is currently
being handled (ZeroDivisionError in this case) and not any exception
that happened to be caught earlier in the current exception handler.
For example,

try:
network.command()
except:
try:
network.close()
except:
pass
raise

I want to make a network call, and if it raises an exception, I want
to close the network connection before allowing the exception to
propagate up the stack. However, trying to close the network
connection might itself raise an exception, and I don't care about
that exception; I want to send the original exception. Apparently the
way to do this is:

try:
network.command()
except Exception, bob:
try:
network.close()
except:
pass
raise bob
 
D

Duncan Booth

SM said:
For example,

try:
network.command()
except:
try:
network.close()
except:
pass
raise

I want to make a network call, and if it raises an exception, I want
to close the network connection before allowing the exception to
propagate up the stack. However, trying to close the network
connection might itself raise an exception, and I don't care about
that exception; I want to send the original exception. Apparently the
way to do this is:

<snip>

You could move the cleanup code out to another scope:

try:
network.command()
except:
def network_cleanup():
try:
network.close()
except:
pass

network_cleanup()
raise

In practice something like network_cleanup probably wants to be called from
more than one place so it could be in a function defined elsewhere.

Another option is to use try..finally:

try:
network.command()
finally:
try:
network.close()
except:
pass

then you don't need to reraise the exception at all.

Use the first suggestion if the cleanup only needs to be done when the code
failed (e.g. to remove partially created files from disc). Use the second
if the cleanup needs to be done always, e.g. closing files or network
connections.
 

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,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top