Is it reasonable in Python to check for a specific type of exception using isinstance?
Asked Answered
G

2

10

Is it reasonable in Python to catch a generic exception, then use isinstance() to detect the specific type of exception in order to handle it appropriately?

I'm playing around with the dnspython toolkit at the moment, which has a range of exceptions for things like a timeout, an NXDOMAIN response, etc. These exceptions are subclasses of dns.exception.DNSException, so I am wondering if it's reasonable, or pythonic, to catch DNSException then check for a specific exception with isinstance().

e.g.

try:
    answers = dns.resolver.query(args.host)
except dns.exception.DNSException as e:
    if isinstance(e, dns.resolver.NXDOMAIN):
        print "No such domain %s" % args.host
    elif isinstance(e, dns.resolver.Timeout):
        print "Timed out while resolving %s" % args.host
    else:
        print "Unhandled exception"

I'm new to Python so be gentle!

Gameto answered 11/2, 2012 at 23:41 Comment(0)
P
20

That's what multiple except clauses are for:

try:
    answers = dns.resolver.query(args.host)
except dns.resolver.NXDOMAIN:
    print "No such domain %s" % args.host
except dns.resolver.Timeout:
    print "Timed out while resolving %s" % args.host
except dns.exception.DNSException:
    print "Unhandled exception"

Be careful about the order of the clauses: The first matching clause will be taken, so move the check for the superclass to the end.

Premeditation answered 11/2, 2012 at 23:43 Comment(1)
Thanks Sven... that looks much nicer.Gameto
M
1

From dns.resolver you can import some exceptions. (untested code)

from dns.resolver import Resolver, NXDOMAIN, NoNameservers, Timeout, NoAnswer

try
    host_record = self.resolver.query(self.host, "A")
    if len(host_record) > 0:
        Mylist['ERROR'] = False
        # Do something

except NXDOMAIN:
    Mylist['ERROR'] = True
    Mylist['ERRORTYPE'] = NXDOMAIN
except NoNameservers:
    Mylist['ERROR'] = True
    Mylist['ERRORTYPE'] = NoNameservers
except Timeout:
    Mylist['ERROR'] = True
    Mylist['ERRORTYPE'] = Timeout
except NameError:
    Mylist['ERROR'] = True
    Mylist['ERRORTYPE'] = NameError
Mutant answered 2/12, 2013 at 8:35 Comment(1)
+1 with the answer: if the exceptions are known, it's better to use different except blocks. But a last except dns.resolver.DNSException would be wise, for handling of sub-exceptions without specific treatment (or to be sure to catch all dns errors).Deportee

© 2022 - 2024 — McMap. All rights reserved.