Reputation: 6346
The following DNS async client works fine if all domains exist.
However, if a domain name doesn't exist, the DNSNameError exception is raised and isn't not catched by my "try except" block. Then, the other domains are not resolve.
I have looking at the documentation of DNSNameError and defer but I didn't find how handle this error with addErrback because I use @inlineCallbacks.
Question : How catch the DNSNameError exception in query() ?
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()
Result:
$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>
Upvotes: 0
Views: 970
Reputation: 48335
First, never use returnValue
outside of a function decorated with inlineCallbacks
. It doesn't make any sense, it will produce surprising results, it'll trigger warnings telling you not to do it, and it'll probably break even worse than it is already broken in some future release of Twisted.
The function you're looking for in query
is defer.succeed
. As in:
...
except:
print "error query"
return defer.succeed(([],[],[]))
But since you're not using inlineCallbacks
on query
, you should add this as an errback instead.
d = resolver.lookupAddress(name)
def queryFailed(reason):
log.err(reason, "Lookup of %s failed" % (name,))
return ([], [], [])
d.addErrback(queryFailed)
return d
Upvotes: 1