关于python:在urlfetch回调中引发的异常

exceptions raised from within a urlfetch callback

当使用回调和在tasklet内执行异步urlfetch调用时,似乎回调内引发的异常不会传播到包装tasklet。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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中被捕获;即,我将得到"只是一个测试"异常报告,而不是输出到控制台的错误消息。

如果有一个与make_fetch_call相关的通用urlfetch异常(如DownloadError在一个错误的url的情况下),它将被正确处理。

在这种情况下,有没有一种方法可以捕获在tasklet内回调生成的异常?或者,这种行为应该被视为bug吗?

谢谢。


我创建了一个示例项目来说明正确的方法。

在阅读代码时,您会发现阅读注释以及与微线程和rpc.make_fetch_Call()上的文档交叉引用有很大的好处。

其中一些令人困惑的方面是,ndb微线程实际上使用异常来指示返回值(即使成功,您也应该使用raise ndb.Return (True),这使得异常处理很难绕过),并且当我们在rpc未来对象r上调用wait()时,需要捕获回调中的异常。由t()返回,而当我们执行yield rpc.make_fetch_call()时,需要在t()本身中捕获URL获取中的异常。可能有一种方法可以使用rpc.check_success()来完成后者,但这将取决于您的黑客行为。

我希望您发现源代码有用,并且希望您学到了避免使用异常来指示生成器已完成的教训…