使用回调和在tasklet中执行异步urlfetch
调用时,似乎从回调中引发的异常不会传播到包装tasklet。
示例代码:
def cb() :
raise Exception, 'just a test'
rpc = urlfetch.create_rpc(callback = cb)
@ndb.tasklet
def t() :
try :
response = yield urlfetch.make_fetch_call(rpc, 'http://...')
except :
print 'an error occured'
raise ndb.Return
t().get_result()
在上面的代码中,由dev服务器执行,“只是一个测试”异常不会被捕获到tasklet中;即。而不是输出到控制台的错误消息我报告了“只是一个测试”异常。
如果存在与urlfetch
相关的通用make_fetch_call
异常(例如,如果网址错误,则为DownloadError
),则会正确处理。
在这种情况下,有没有办法在tasklet中捕获回调生成的异常?或者也许这种行为应该被视为一个错误?
感谢。
答案 0 :(得分:2)
我已创建sample project来说明执行此操作的正确方法。
在阅读代码时,您会发现阅读评论以及与tasklets和rpc.make_fetch_call()上的文档交叉引用会带来很多好处。
这有一些令人困惑的方面是ndb tasklets实际上使用Exceptions来指示返回值(即使成功,你应该raise ndb.Return (True)
,使得异常处理难以tip脚),以及异常这一事实当我们在wait()
返回的rpc
未来对象上调用t()
时,需要捕获回调函数,而url fetch中的异常需要在t()
本身内部被捕获我们做yield rpc.make_fetch_call()
。可能有一种方法可以使用rpc.check_success()来完成后者,但是这将由你的黑客来决定。
我希望你找到有用的资料,我希望你学到了一个关于避免使用异常来表明生成器已经完成的教训......