Reputation: 44305
I have a method that checks something and which can
I want catch the exception properly to raise one myself, but also if the test returns False. The incorrect way to do this is
try:
if not check():
raise MyException()
except:
raise MyException()
as the first MyException
is caught after the except
again. One way to handle this properly would be
try:
flag = check()
except:
raise MyException()
else:
if not flag:
raise MyException()
Is this the only way of dealing with this situation, or is there another way to handle it more efficient, getting rid of the flag
variable?
Upvotes: 7
Views: 23416
Reputation: 2938
You should never use except: because that catches ALL exceptions, including SystemExit, you should probably do:
try:
if not check():
raise MyNewException()
except ExceptionRaisedByCheck:
raise MyNewException()
If the exception coming from check() is the same as the one you want to raise, you should change that.
Edit: If the exception is the same, you can also simply do this (Mark Byers had this in his answer, but it's gone now):
if not check():
raise TheSameException()
This will propagate the exception or raise if False.
Upvotes: 12
Reputation: 1121584
In python 3.3, you can use the new contextlib.ExitStack
context manager:
with ExitStack() as stack:
stack.callback(lambda: raise MyException)
if check():
stack.pop_all()
This will raise MyException
, unless you clear the stack callbacks with pop_all()
.
You can codify this is into a custom context manager:
from contextlib import ExitStack
class ExceptionUnlessCancelled(ExitStack):
def __init__(self, exception, *args, **kw):
super(Callback, self).__init__()
self.exception = exception
self.callback(self.raiseException, *args, **kwds)
def raiseException(self, *args, **kw):
raise self.exception(*args, **kw)
def cancel(self):
self.pop_all()
with ExceptionUnlessCancelled(MyException) as exc:
if check():
exc.cancel()
Upvotes: 1
Reputation: 414149
try:
# whatever
except MyException:
raise # reraise it
except Exception as e:
raise MyException(some_info(e)) # unify user-visible exception type
Upvotes: 2