Is there a way to continue after an exception ?
Lie Ryan
lie.1296 at gmail.com
Sat Feb 20 21:17:47 EST 2010
On 02/21/10 12:02, Stef Mientki wrote:
> On 21-02-2010 01:21, Lie Ryan wrote:
>>> On Sun, Feb 21, 2010 at 12:52 AM, Stef Mientki
<stef.mientki at gmail.com> wrote:
>>>
>>>> hello,
>>>>
>>>> I would like my program to continue on the next line after an uncaught
>>>> exception,
>>>> is that possible ?
>>>>
>>>> thanks
>>>> Stef Mientki
>>>>
>>>>
>> That reminds me of VB's "On Error Resume Next"
>>
> I think that's what I'm after ...
First, read this:
http://www.developerfusion.com/code/4325/on-error-resume-next-considered-harmful/
> I already redirected sys.excepthook to my own function,
> but now I need a way to get to continue the code on the next line.
> Is that possible ?
No, not in python. You can (ab)use generators' yield to resume
execution, but not in the general case:
def on_error_resume_next(func):
def _func(*args, **kwargs):
gen = func(*args, **kwargs)
resp = next(gen)
while isinstance(resp, Exception):
print 'an error happened, ignoring...'
resp = next(gen)
return resp
return _func
@on_error_resume_next
def add_ten_error_if_zero(args):
if args == 0:
# raise Exception()
yield Exception()
# return args + 10
yield args + 10
print add_ten_error_if_zero(0)
print add_ten_error_if_zero(10)
A slightly better approach is to retry calling the function again, but
as you can see, it's not appropriate for certain cases:
def retry_on_error(func):
def _func(*args, **kwargs):
while True:
try:
ret = func(*args, **kwargs)
except Exception:
print 'An error happened, retrying...'
else:
return ret
return _func
@retry_on_error
def add_ten_error_if_zero(args):
if args == 0:
raise Exception()
return args + 10
print add_ten_error_if_zero(0)
print add_ten_error_if_zero(10)
A much better approach is to use callbacks, the callbacks determines
whether to raise an exception or continue execution:
def handler(e):
if datetime.datetime.now() >= datetime.datetime(2012, 12, 21):
raise Exception('The world has ended')
# else: ignore, it's fine
def add_ten_error_if_zero(args, handler):
if args == 0:
handler(args)
return args + 10
print add_ten_error_if_zero(0, handler)
print add_ten_error_if_zero(10, handler)
print add_ten_error_if_zero(0, lambda e: None) # always succeeds
Ignoring arbitrary error is against the The Zen of Python "Errors should
never pass silently."; not that it is ever a good idea to ignore
arbitrary error, when an exception happens often the function is in an
indeterminate state, and continuing blindly could easily cause havocs.
More information about the Python-list
mailing list