2013-04-11 107 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