【问题标题】:Handle error on a simple DNS Twisted Client处理简单 DNS Twisted 客户端上的错误
【发布时间】:2013-04-03 09:39:15
【问题描述】:

如果所有域都存在,则以下 DNS 异步客户端可以正常工作。

但是,如果域名不存在,则会引发 DNSNameError 异常,并且不会被我的“try except”块捕获。然后,其他域不解析。

我查看了DNSNameErrordefer 的文档,但我没有找到如何使用addErrback 处理此错误,因为我使用的是@inlineCallbacks

问题:如何在query()中捕获DNSNameError异常?

from itertools import cycle
from pprint import pprint
from twisted.names import client, dns
from twisted.internet.task import react
from twisted.internet import defer, reactor

def query(reactor, server, name):

    resolver = client.Resolver(
        resolv="/dev/null", servers=[(server, 53)], reactor=reactor)

    try:
        return resolver.lookupAddress(name)
    except:
        print "error query"
        return defer.returnValue(([],[],[]))


@defer.inlineCallbacks
def main(reactor, names):
    servers = ["4.2.2.1", "8.8.8.8"]

    next_server = cycle(servers).next

    results = []
    for n in names:
        try:
            results.append(query(reactor, next_server(), n))
        except:
            print "error append"


    try:
        results = yield defer.gatherResults(results)
        print "Success."
    except:
        print "Error result"
    finally:
        print "Shutting down"
        reactor.stop()

    pprint(zip(names, results))

if __name__ == '__main__':
    main(reactor, ('google.com', 'notexist.www','google.fr',))
    reactor.run()

结果:

$ipython twisteddns.py 
ipython twisteddns.py 
Error result
Shutting down
[('google.com', <Deferred at 0xad862ac>),
 ('notexist.www',
  <Deferred at 0xad8666c current result: <twisted.python.failure.Failure <class 'twisted.names.error.DNSNameError'>>>),
 ('google.fr', <Deferred at 0xad869ac>)]
Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
Failure: twisted.names.error.DNSNameError: <twisted.names.dns.Message instance at 0xad86a6c>

【问题讨论】:

    标签: python asynchronous dns twisted


    【解决方案1】:

    首先,切勿在用inlineCallbacks 装饰的函数之外使用returnValue。这没有任何意义,它会产生令人惊讶的结果,它会触发警告告诉你不要这样做,而且它可能会比在 Twisted 的某些未来版本中已经被破坏的情况更糟。

    您在query 中寻找的函数是defer.succeed。如:

    ...
    except:
        print "error query"
        return defer.succeed(([],[],[]))
    

    但由于您query 上使用inlineCallbacks,因此您应该将其添加为errback。

    d = resolver.lookupAddress(name)
    def queryFailed(reason):
        log.err(reason, "Lookup of %s failed" % (name,))
        return ([], [], [])
    d.addErrback(queryFailed)
    return d
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 2018-02-10
      • 2013-08-26
      • 1970-01-01
      相关资源
      最近更新 更多