Exceptions processing in gen.Task #411

Closed
wants to merge 5 commits into
from

Projects

None yet

4 participants

Contributor
kachayev commented Dec 5, 2011

It solves this issue:
#405

So this code:

from tornado import ioloop
from tornado import gen
io_loop = ioloop.IOLoop.instance()

def async_func(callback):
    10/0
    io_loop.add_callback(lambda: callback(100))

@gen.engine
def main():
    try:
        num = yield gen.Task(async_func)
    except Exception as e:
        print 'Here our exception:', str(e)
    else:
        print num
    finally:
        io_loop.stop()

if __name__=='__main__':
    main()
    io_loop.start()

will have next output:

Here our exception: integer division or modulo by zero
perol commented Dec 6, 2011

Thanks @kachayev,

It's great, exactly resolve my problem.

but when in @gen.engine call another gen.Task, the outest caller still can't catch the gen.Tash error.

code below.

I'd try to fix it, but it always don't work.

import thunder

from tornado import ioloop
from tornado import gen
io_loop = ioloop.IOLoop.instance()

def async_func2(callback):
    #10/0
    io_loop.add_callback(lambda: callback(999999999))

@gen.engine
def async_func(callback):
    #10/0
    print (yield gen.Task(async_func2))
    10/0
    io_loop.add_callback(lambda: callback(100))

@gen.engine
def main():
    try:
        num = yield gen.Task(async_func)
    except Exception as e:
        print '################'+str(e)+'################'
    else:
        print num
    finally:
        io_loop.stop()

if __name__=='__main__':
    main()
    io_loop.start()
Contributor
kachayev commented Dec 6, 2011

@perol I'm working with this issue already.

Owner
bdarnell commented Dec 7, 2011

This looks like a good change, but I'd like to see a unittest added for it. Also, I think it should probably throw the entire sys.exc_info() triple into the generator instead of just the exception object.

@chilkari chilkari pushed a commit to chilkari/tornado that referenced this pull request Dec 7, 2011
@dm-jonathonwilson dm-jonathonwilson Add test for #411, test Task exception is catchable c72f220
Contributor
kachayev commented Dec 9, 2011

@chilkari I didn't see your commit, sorry :)

chilkari commented Dec 9, 2011

No worries. /me is new to github. Didn't even realize by referencing this issue in my own commit it would auto-comment here (cool). Anyways, was just trying to save you some work. I'm interested in this fix as well. Thanks!

Contributor
kachayev commented Dec 9, 2011

@bdarnell I added two tests and reimplemented first approach with additional handling of nested gen.Runner. It just works, but it seems to be not perfect solution.

  1. Possible it will be better to use ExceptionStackContext here in order to catch exceptions in async func.
  2. I think it will be good to give facilities for working with custom exceptions handler (which can be passed as error_callback to gen.Taks for ex.)

Any comments?

@bdarnell bdarnell closed this in ac9902c Jan 2, 2012
@adamaflynn adamaflynn pushed a commit to ContextLogic/tornado that referenced this pull request Mar 19, 2013
Adam Flynn Use a StackContext to allow exceptions thrown from asynchronous funct…
…ions

called by a generator to be caught normally.

Closes #405.
Closes #411.

Conflicts:

	tornado/gen.py
	tornado/test/gen_test.py
9aa5301
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment