sleblanc
sleblanc

Reputation: 3921

Python: How to ignore an exception while still handling others

I was messing with some code and was faced with a particular problem:

def find_available_slug(object, instance, slug)
    try:
        sender_node = object.objects.get(slug=slug)
    except object.DoesNotExist:
        instance.slug = slug
    else:
        slug = '%s_' % slug
        find_available_slug(object, instance, slug)
    return

The issue I am having is that sometimes objects.get(slug=slug) throws a MultipleObjectsReturned exception because that field is not unique within my database. I wonder how I can cleanly catch MultipleObjectsReturned while the "else" statement will still get executed.

Upvotes: 1

Views: 1309

Answers (2)

nneonneo
nneonneo

Reputation: 179382

Alternatively, don't use the else clause at all:

def find_available_slug(object, instance, slug)
    try:
        sender_node = object.objects.get(slug=slug)
    except object.DoesNotExist:
        instance.slug = slug
        return
    except object.MultipleObjectsReturned:
        pass

    slug = '%s_' % slug
    find_available_slug(object, instance, slug)

Upvotes: 2

sleblanc
sleblanc

Reputation: 3921

Simple solution: the trick is to trap MultipleObjectsReturned inside a second try statement, when calling the get method. This way, no exception is raised and execution continues normally.

Works:

def find_available_slug(object, instance, slug)
    try:
        try:
            sender_node = object.objects.get(slug=slug)
        except object.MultipleObjectsReturned:
            pass
    except object.DoesNotExist:
        instance.slug = slug
    else:
        slug = '%s_' % slug
        find_available_slug(object, instance, slug)
    return

Does not work:

def find_available_slug(object, instance, slug)
    try:
        sender_node = object.objects.get(slug=slug)
    except object.MultipleObjectsReturned:
        pass
    except object.DoesNotExist:
        instance.slug = slug
    else:
        slug = '%s_' % slug
        find_available_slug(object, instance, slug)
    return

The reason the second "naive" method does not work is that if an exception is caught, the interpreter will not go through the else: clause. It would instead silently return.

Upvotes: 2

Related Questions