Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 658
generic purple turtle Avatar asked Oct 15 '25 17:10

generic purple turtle


1 Answers

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
like image 186
Szabolcs Avatar answered Oct 18 '25 01:10

Szabolcs



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!