Reputation: 7118
I have code that's a bit like this:
try:
# do stuff
except SomeSpecificException as sse:
if sse.some_property == some_special_value:
# handle the exception in a special way
else:
handle_exception_normally()
except:
handle_exception_normally()
I want to catch the specific exception and handle it in a special way, but only if it has a particular property. If it doesn't have that property, I want it to be handled just like any other exception (logging, screaming, etc.)
The code above works, but if possible, I want to avoid repeating handle_exception_normally()
(DRY and all that).
Just putting raise
in the else
clause of the first except
block does not work. A parent try
block would catch that, but the catch-all clause in the same block will not.
I could nest two try
blocks, but it's not very elegant; I'd rather just use
the code I have above.
Is there a better way?
Note that I'm using Python 3.
Upvotes: 2
Views: 99
Reputation: 45291
I understand OP said they do not want to do this, but I'm throwing my lot in with the nested try
block. I think it's the most readable way to go about this:
try:
try:
# do stuff
except SomeSpecificException as sse:
if sse.some_property == some_special_value:
# handle the exception in a special way
else:
raise
except:
handle_exception_normally()
Upvotes: 0
Reputation: 4972
I would opt for:
try:
# do stuff
except Exception as e:
if e.args[0] == 'Discriminate Exception Here' and sse.some_property == some_special_value:
# handle the exception in a special way
else:
handle_exception_normally()
Moses Koledoye proposed:
try:
# do stuff
except Exception as e:
if getattr(e, 'some_property', None) == some_special_value:
# handle the exception in a special way
else:
handle_exception_normally()
Which is shorter but requires some_special_value to always be != None
and attribute to be unique to your exception.
Examples of exception discrimination, with e.args[0]
:
try:
5 / 0
except Exception as e:
print(e.args[0])
division by zero
With __class__.__name__
:
try:
5 / 0
except Exception as e:
print(e.__class__.__name__)
ZeroDivisionError
With isinstance()
(bit more CPU intensive) :
try:
5 / 0
except Exception as e:
isinstance(e, ZeroDivisionError)
True
Upvotes: 5