【问题标题】:exceptions raised from within a urlfetch callback从 urlfetch 回调中引发的异常
【发布时间】:2014-10-17 10:50:12
【问题描述】:

当使用回调和在 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()

在上面的代码中,由开发服务器执行,“只是一个测试”异常不会在 tasklet 中被捕获; IE。而不是将错误消息输出到控制台,而是报告了“只是一个测试”异常。

如果存在与make_fetch_call 相关的通用urlfetch 异常(例如DownloadError,如果URL 不正确),则会正确处理。

在这种情况下,有没有办法在 tasklet 中捕获回调生成的异常?还是应该将此行为视为错误?

谢谢。

【问题讨论】:

  • 如果您的网址中有空格,请将其替换为 %20 它将帮助您解决问题

标签: python google-app-engine asynchronous urlfetch


【解决方案1】:

我创建了一个sample project 来说明执行此操作的正确方法。

在阅读代码时,您会发现阅读 cmets 以及与 taskletsrpc.make_fetch_call() 上的文档进行交叉引用会带来很多好处。

其中一些令人困惑的方面是 ndb tasklet 实际上使用 Exceptions 来指示返回值(即使成功,您也应该 raise ndb.Return (True),使得异常处理难以小心翼翼地处理),以及在当我们在t() 返回的rpc 未来对象上调用wait() 时需要捕获回调,而当我们执行yield rpc.make_fetch_call() 时,需要在t() 自身内部捕获url 获取中的异常。可能有一种方法可以使用 rpc.check_success() 来完成后者,但这取决于您的黑客行为。

我希望源代码对您有所帮助,并且希望您学到了有关避免使用异常来指示生成器已完成的教训...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多