Lucubrator
Lucubrator

Reputation: 1187

Exception handling: Differentiating between instances of the same error in Python

What is the recommended way of separately handling exceptions of the same type based on differences in what caused the exception?

Let's say one desire to handle the following two instances of AttributeError differently:

At the same time, we don't want to handle other attribute errors.

Are there any generalizable answers that work for all exception types? Can I interrogate the exception object for details using some method or function on the exception object?

Try:
    blah
Except AttributeError as exc:
    if exc.baz('foo') is bar:
         handle 'str' object has no attribute 'append'
    elif plugh(exc):
         handle 'float' object has no attribute 'append'
    else:
         raise exc

I assume that the obvious answer is to refactor. My question specifically regards the cases where that would be inefficient or simply not possible (if there are any such cases at all).

Upvotes: 2

Views: 684

Answers (1)

roganjosh
roganjosh

Reputation: 13175

You can see what methods and attributes an object has by using dir.

In Python 3.6, from:

a = 'hello'
try:
    a.append(2)
except AttributeError as e:
    print(dir(e))

You get:

['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'with_traceback']

That narrows down the things we can test since we don't want a dunder, leaving only args and with_traceback. It seems then that the best you could get is to use args which returns the string in a tuple:

a = 'hello'
try:
    a.append(2)
except AttributeError as e:
    if 'str' in e.args[0]:
        print('Need to handle string')
    elif 'float' in e.args[0]:
        print('Need to handle float')

Upvotes: 1

Related Questions