Search code examples
pythonerror-handlingdry

A DRY approach for multiple excepts


Let's assume we have a following code:

try:
    whatever
except ValueError:
    something1
except (IndexError, KeyError):
    something2
except KeyBoardInterrupt:
    something3
except Exception:
    something4
else:  # no error
    something5
finally:
    finalize

So we have multiple excepts. Do we have any else-antipod that will suit DRY approach, so this will be executed only if any error happened?

For example, we want to set some error variable/flag or log the error, but apart of that execute different except logic without writing a method/func except_logic() and calling it in every except.


Solution

  • A cleaner approach would be to use a catch-all exception handler to handle any exception with the same shared logics, but then reraise the exception in a nested exception handler for type-specific exception handling logics:

    try:
        something()
    except Exception as e:
        log_exception(e)
        try:
            raise
        except ValueError:
            process_valueerror(e)
        except (IndexError, KeyError):
            process_indexerror_keyerror(e)
        # more shared logics can run here after type-specific logics
        post_processing(e)
    

    Demo: https://ideone.com/vlEXtu

    You can also use @deceze's solution in the comments by explicitly testing the type of the exception with if statements instead:

    try:
        something()
    except Exception as e:
        log_exception(e)
        if isinstance(e, ValueError):
            process_valueerror(e)
        elif isinstance(e, (IndexError, KeyError)):
            process_indexerror_keyerror(e)
        # more shared logics can run here after type-specific logics
        post_processing(e)
    

    This saves 2 lines by not having to reraise the exception but at the same time it adds the boilerplate of calling isinstance(e, ...) for each addtional error handler, so it comes down to the personal taste which approach you prefer.