Use match case to handle exceptions

I have a method that receives an exception of type Exception as a parameter and I want to filter which exceptions to show to the user and which to show as general errors.

Since I have more than 10 of these exceptions in the real code, I wanted to use a match case that filters out the different cases.

I only want to match the type of exceptions and I don’t want to use an if elif for each exception if possible, as code inside each if would be the same.

def handle_exception(self, exception: Exception):
    # Built the error message, based on which exception was caught
    match exception:
        case MyCustomExceptionOne() \
             | MyCustomExceptionTwo() \
             | MyCustomExceptionThree():
            show_error_message(exception) 
        case _:
            show_error_message("Error occured") 

Am I missing something?

>Solution :

There is no need nor advantage for case match just to match multiple types: An if can efficiently match on multiple types using if isinstance(obj, (type1, type2, ...)).

def handle_exception(self, exception: Exception):
    # Built the error message, based on which exception was caught
    if isinstance(
        exception,
        (MyCustomExceptionOne, MyCustomExceptionTwo, MyCustomExceptionThree)
    ):
        show_error_message(exception) 
    else:
        show_error_message("Error occured") 

This is equivalent to what except (type1, type2, ...): does under the hood, thus matching the usual exception handling semantics.

Note that the second argument to isinstance is a regular tuple here. If code clarity is an issue, it can be defined elsewhere and simply referenced:

MY_EXCEPTIONS = (MyCustomExceptionOne, MyCustomExceptionTwo, MyCustomExceptionThree)

def handle_exception(self, exception: Exception):
    # Built the error message, based on which exception was caught
    if isinstance(exception, MY_EXCEPTIONS):
        show_error_message(exception) 
    else:
        show_error_message("Error occured") 

Leave a Reply