Jaap Joris Vens
Jaap Joris Vens

Reputation: 3560

What's an elegant way to catch the same exception multiple times?

I have some Python code that tries a bunch of different database queries before it concludes that the database is empty and gives up. Here is a simplified example:

try:
    result = Object.get(name="requested_object")
except Object.DoesNotExist:
    try:
        result = Object.get(name="default_object")
    except Object.DoesNotExist:
        try:
            result = Object.get(pk=1)
        except Object.DoesNotExist:
            print "The database is empty!"
            raise

Note that the exception I'm trying to catch is the same every time. Surely there must be a way to do this without needless repetition and nesting. How can I achieve the same behavior without the nested try...except statements?

Upvotes: 11

Views: 4466

Answers (2)

georg
georg

Reputation: 214999

Nested and complicated control blocks are easier to read when wrapped into a function:

def result():
    try:
        return Object.get(name="requested_object")
    except Object.DoesNotExist:
        pass

    try:
        return Object.get(name="default_object")
    except Object.DoesNotExist:
        pass

    return Object.get(pk=1) # NB: no "try" here. If it's going to fail, let it fail

This way you avoid excessive indentation and "mental jumps" like break/continue.

Upvotes: 5

Ned Batchelder
Ned Batchelder

Reputation: 375744

for args in [{'name':"requested_object"}, {'name':"default_object"}, {'pk':1}]:
    try:
        result = Object.get(**args)
    except Object.DoesNotExist as e:
        continue
    else:
        break
else:
    raise e

It's not clear what exception you want to raise if you never find what you want, you might have to adjust that part. Also, the scoping of exception values has changed in Python 3, so e won't be available to raise.

Upvotes: 8

Related Questions