Twisted 有时抛出(似乎不完整的)“超过最大递归深度”RuntimeError
因为Twisted的getPage
函数不能让我访问请求头,所以我不得不自己写一个getPageWithHeaders
函数。
def getPageWithHeaders(contextFactory=None, *args, **kwargs):
try:
return _makeGetterFactory(url, HTTPClientFactory,
contextFactory=contextFactory,
*args, **kwargs)
except:
traceback.print_exc()
这个函数和普通的getPage
函数完全一样,只是我加了一个try/except块,并且返回的是工厂对象,而不是返回工厂的deferred。
奇怪的是,我有时候会在这里遇到“最大递归深度超出”的错误。这种情况在700次中大约会发生几次,通常每次都是在不同的网站上。有人能帮我解释一下吗?我不太明白为什么会这样,而且Twisted的代码库很大,我都不知道该从哪里入手。
编辑:这是我得到的错误追踪信息,看起来奇怪得不完整:
Traceback (most recent call last):
File "C:\keep-alive\utility\background.py", line 70, in getPageWithHeaders
factory = _makeGetterFactory(url, HTTPClientFactory, timeout=60 , contextFactory=context, *args, **kwargs)
File "c:\Python26\lib\site-packages\twisted\web\client.py", line 449, in _makeGetterFactory
factory = factoryFactory(url, *args, **kwargs)
File "c:\Python26\lib\site-packages\twisted\web\client.py", line 248, in __init__
self.headers = InsensitiveDict(headers)
RuntimeError: maximum recursion depth exceeded
这是整个错误追踪信息,明显没有长到会超出我们的最大递归深度。我还需要做些什么才能得到完整的堆栈信息吗?我以前从来没有遇到过这个问题;通常当我做类似的事情时
def f(): return f()
try: f()
except: traceback.print_exc()
我会得到那种“最大递归深度超出”的堆栈信息,里面会有很多对f()
的引用。
3 个回答
这个网址打开器可能正在经历一连串不断的301或302重定向。
你应该看看你收到的错误信息和异常提示,这会告诉你哪个函数在不断地重复调用,也就是在_makeGetterFactory
下面的那些函数。很可能是你自己写的getPageWithHeaders
函数参与了这个重复调用,因为它没有正确地返回一个“延迟”对象,而是试图返回一个还没准备好的工厂。如果你真的改回去,返回那个“延迟”对象,会发生什么呢?
你看到的这个错误追踪信息有点让人困惑。你可以试试用 traceback.print_stack
,而不是 traceback.print_exc
,这样可以查看到出问题的代码上面所有的调用记录,而不仅仅是异常被捕获的地方。
我不能确定,因为我没有看到更多的错误追踪信息,但你可能遇到了一个问题,就是如果你把太多的 Deferred(延迟对象)串在一起,就会引发递归限制的异常。你可以在这里查看相关信息:这个链接。
如果你开启 Deferred 的调试模式(用 from twisted.internet.defer import setDebugging; setDebugging(True)
),在某些情况下你可能会得到更有用的错误追踪信息,但请注意,这样可能会让你的服务器变得比较慢。