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