Twisted:在互联网连接断开时捕获 DNSLookupError
Twisted: catching DNSLookupError upon internet connection drop
我有一个简单的 twisted
脚本,它向某些 API 端点发送 GET 请求。它工作正常,除了当我的互联网连接断开时它会用一堆 Unhandled error in Deferred:
消息污染日志。
最小示例如下所示:
import sys
from twisted.web.client import Agent
from twisted.internet import reactor, task
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Protocol
from twisted.logger import Logger, textFileLogObserver
# the DNSLookupError gets thrown before an instance of this class
# is created
class DataReceiver(Protocol):
def __init__(self, finished):
self.finished = finished
def dataReceived(self, data):
log.info('Got data!')
def connectionLost(self, reason):
log.info(reason.getErrorMessage())
self.finished.callback(None)
def receive_data(response):
try:
response.deliverBody(DataReceiver(Deferred()))
except Exception as e:
log.failure(e)
def schedule_request(agent):
try:
req = agent.request(b'GET', b'https://www.example.org')
req.addCallbacks(receive_data, errback=log.failure)
except Exception as e:
log.failure(e)
if __name__ == '__main__':
log = Logger(observer=textFileLogObserver(sys.stdout))
try:
# schedule requests every two seconds
agent = Agent(reactor)
loop = task.LoopingCall(lambda: schedule_request(agent))
loop.start(2)
# run event loop
reactor.run()
except Exception as e:
log.failure(e)
当互联网连接正常时,日志看起来像预期的那样:
2018-02-06T16:50:32+0100 [__main__#info] Got data!
2018-02-06T16:50:32+0100 [__main__#info] Response body fully received
但是当连接断开时我看到:
Unhandled error in Deferred:
如果我使用来自 twisted.python
的日志,完整的回溯是:
2018-02-06 16:42:54+0100 [-] Unhandled Error
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/_resolver.py", line 137, in deliverResults
resolutionReceiver.resolutionComplete()
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/endpoints.py", line 900, in resolutionComplete
d.callback(addresses)
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/defer.py", line 459, in callback
self._startRunCallbacks(result)
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/defer.py", line 567, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/defer.py", line 653, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/endpoints.py", line 954, in startConnectionAttempts
"no results for hostname lookup: {}".format(self._hostStr)
twisted.internet.error.DNSLookupError: DNS lookup failed: no results for hostname lookup: www.example.org.
如何在 twisted
中捕捉并处理这个异常?
您的应用程序代码正在记录此失败:
req.addCallbacks(receive_data, errback=log.failure)
当 req
Deferred
由于此 DNS 错误而失败时,将调用 errback。如果您不想记录这种情况,请更改您的 errback。例如:
def do_not_log_dns_errors(failure):
if not failure.check(DNSLookupError):
log.failure("request failed", failure)
(另请注意 log.failure
的第一个参数不是 Failure
)。
我有一个简单的 twisted
脚本,它向某些 API 端点发送 GET 请求。它工作正常,除了当我的互联网连接断开时它会用一堆 Unhandled error in Deferred:
消息污染日志。
最小示例如下所示:
import sys
from twisted.web.client import Agent
from twisted.internet import reactor, task
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Protocol
from twisted.logger import Logger, textFileLogObserver
# the DNSLookupError gets thrown before an instance of this class
# is created
class DataReceiver(Protocol):
def __init__(self, finished):
self.finished = finished
def dataReceived(self, data):
log.info('Got data!')
def connectionLost(self, reason):
log.info(reason.getErrorMessage())
self.finished.callback(None)
def receive_data(response):
try:
response.deliverBody(DataReceiver(Deferred()))
except Exception as e:
log.failure(e)
def schedule_request(agent):
try:
req = agent.request(b'GET', b'https://www.example.org')
req.addCallbacks(receive_data, errback=log.failure)
except Exception as e:
log.failure(e)
if __name__ == '__main__':
log = Logger(observer=textFileLogObserver(sys.stdout))
try:
# schedule requests every two seconds
agent = Agent(reactor)
loop = task.LoopingCall(lambda: schedule_request(agent))
loop.start(2)
# run event loop
reactor.run()
except Exception as e:
log.failure(e)
当互联网连接正常时,日志看起来像预期的那样:
2018-02-06T16:50:32+0100 [__main__#info] Got data!
2018-02-06T16:50:32+0100 [__main__#info] Response body fully received
但是当连接断开时我看到:
Unhandled error in Deferred:
如果我使用来自 twisted.python
的日志,完整的回溯是:
2018-02-06 16:42:54+0100 [-] Unhandled Error
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/_resolver.py", line 137, in deliverResults
resolutionReceiver.resolutionComplete()
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/endpoints.py", line 900, in resolutionComplete
d.callback(addresses)
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/defer.py", line 459, in callback
self._startRunCallbacks(result)
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/defer.py", line 567, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/defer.py", line 653, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "/usr/local/lib/python3.5/dist-packages/twisted/internet/endpoints.py", line 954, in startConnectionAttempts
"no results for hostname lookup: {}".format(self._hostStr)
twisted.internet.error.DNSLookupError: DNS lookup failed: no results for hostname lookup: www.example.org.
如何在 twisted
中捕捉并处理这个异常?
您的应用程序代码正在记录此失败:
req.addCallbacks(receive_data, errback=log.failure)
当 req
Deferred
由于此 DNS 错误而失败时,将调用 errback。如果您不想记录这种情况,请更改您的 errback。例如:
def do_not_log_dns_errors(failure):
if not failure.check(DNSLookupError):
log.failure("request failed", failure)
(另请注意 log.failure
的第一个参数不是 Failure
)。