2013-04-11 58 views
0

如果所有域都存在,则以下DNS异步客户端可以正常工作。在简单的DNS扭曲客户端上处理错误

但是,如果一个域名不存在,则会引发DNSNameError异常,并且不会被我的“尝试除外”块捕获。然后,其他域不解决。

我一直在寻找的DNSNameErrordefer的文档,但我没有找到如何与addErrback处理这个错误,因为我用@inlineCallbacks

问题:如何捕获中的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> 

回答

1

首先,从来没有使用returnValue外面饰以inlineCallbacks函数。它没有任何意义,它会产生令人惊讶的结果,它会引发警告,告诉你不要这样做,它可能会比在Twisted的未来版本中已经破坏的更坏。

您在query寻找的功能是defer.succeed。如:

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

但既然你在使用queryinlineCallbacks,你应该将其添加为一个errback可代替。

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