【问题标题】:Twisted: catching DNSLookupError upon internet connection dropTwisted:在 Internet 连接断开时捕获 DNSLookupError
【发布时间】:2018-07-16 18:34:16
【问题描述】:

我有一个简单的twisted 脚本,它将 GET 请求发送到某个 API 端点。它工作正常,除了当我的互联网连接断开时,它会用一堆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 中捕获和处理此异常?

【问题讨论】:

    标签: python python-3.x twisted twisted.internet


    【解决方案1】:

    您的应用程序代码正在记录此故障:

    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)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多