generic purple turtle
generic purple turtle

Reputation: 471

How to catch different exceptions of the same type?

I find myself in a situation similar to the code below.

I have a try block, and I am testing the values of two different variables. If one of them is incorrect I would like to raise an exception a ValueError exception, but I would like to handle them differently depending on which one occurs.

fingers = 8
thumbs = 3

try:
    if fingers == 8:
        print("8 Is the usual amount of fingers")
    else:
        raise ValueError("That's a strange amount of fingers to have")

    if thumbs ==  2:
        print("You have the usual amount of thumbs")
    else:
        raise ValueError("That's a strange amount of thumbs to have")

except ValueError as e1:
    print("You had the wrong amount of fingers - let me perform surgery and fix that for you")
    fingers = 8

except ValueError as e2:
    print("You had the wrong amount of thumbs - let me perform surgery and fix that for you")
    thumbs = 2

Obviously as it's written now, this error gets incorrectly caught as the finger one. Is there a way to catch them seperately somehow while still throwing a value error exception? Or do I need to create two seperate custom exception classes to deal with a situation like this?

Upvotes: 3

Views: 1150

Answers (2)

Szabolcs
Szabolcs

Reputation: 4086

You could pass arbitrary amount of arguments to a ValueError, so you can distinguish your errors if you want:

fingers = 8
thumbs = 3

try:
    if fingers == 8:
        print("8 Is the usual amount of fingers")
    else:
        raise ValueError("That's a strange amount of fingers to have", "fingers")

    if thumbs == 2:
        print("You have the usual amount of thumbs")
    else:
        raise ValueError("That's a strange amount of thumbs to havet", "thumbs")

except ValueError as err:
    if err.args[1] == "fingers":
        print(
            "You had the wrong amount of fingers - let me perform surgery and fix that for you"
        )
        fingers = 8

    if err.args[1] == "thumbs":
        print(
            "You had the wrong amount of thumbs - let me perform surgery and fix that for you"
        )
        thumbs = 2

As you can see I've passed "fingers" and "thumbs" as a second argument to the respective errors, and then later using the error argument list I could find out which one of them was raised.

Also let me note that although it works, I don't see any particular reason not to go for your custom exception classes, they make your code easier to read and more reasonable:

fingers = 8
thumbs = 2


class FingersValueError(ValueError):
    pass


class ThumbsValueError(ValueError):
    pass


try:
    if fingers == 8:
        print("8 Is the usual amount of fingers")
    else:
        raise FingersValueError("That's a strange amount of fingers to have", "fingers")

    if thumbs == 2:
        print("You have the usual amount of thumbs")
    else:
        raise ThumbsValueError("That's a strange amount of thumbs to havet", "thumbs")

except FingersValueError:

    print(
        "You had the wrong amount of fingers - let me perform surgery and fix that for you"
    )
    fingers = 8

except ThumbsValueError:
    print(
        "You had the wrong amount of thumbs - let me perform surgery and fix that for you"
    )
    thumbs = 2

And since the custom errors are derived from ValueError you can also catch them in a single except block and then check their type:

except ValueError as err:

    if isinstance(err, FingersValueError):
        print(
            "You had the wrong amount of fingers - let me perform surgery and fix that for you"
        )
        fingers = 8

    if isinstance(err, ThumbsValueError):
        print(
            "You had the wrong amount of thumbs - let me perform surgery and fix that for you"
        )
        thumbs = 2

Upvotes: 7

ericl16384
ericl16384

Reputation: 364

Try this slight modification.

fingers = 8

thumbs = 3

if fingers == 8:
    print("8 Is the usual amount of fingers")
else:
    print("You had the wrong amount of fingers - let me perform surgery and fix that for you")
    fingers = 8
        
if thumbs ==  2:
    print("You have the usual amount of thumbs")
else:
    print("You had the wrong amount of thumbs - let me perform surgery and fix that for you")
    thumbs = 2

If that does not work for you, use two separate try except statements.

Then, if that still does not work, create a child classes of the exception, and look for the child classes.

Upvotes: 0

Related Questions