Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python efficient exception handling

Tags:

python

I'm trying to figure out if there's a more pythonic way to do a specific error handling task. I want to catch multiple specific custom exceptions and do something specific depending on which exception is caught (like use a specific custom exit code, or add a specific log message, etc...). However, I also want, if any exception is raised, to do send an email saying the script didn't complete successfully, had exit code __, the log is at C:\foo\bar.txt

I know I could include everything I want to do in each except, such as:

try:
    do_something()
except CustomError1:
    exitcode = 1
    send_error_email(exitcode)
    sys.exit(exitcode)
except CustomError2:
    exitcode = 2
    send_error_email(exitcode)
    sys.exit(exitcode)

But I'm wondering if there's a more pythonic or more efficient way of doing it. I'm imagining something like

try:
    do_something()
except CustomError1:
    exitcode = 1
except CustomError2:
    exitcode = 2
except ParrentCustomErrorClass:
    send_error_email()
    sys.exit(exitcode)

If it matters, I'm currently stuck with python 2.7, but need to be able to port solution to 3.x when 3rd party applications allow it.

like image 943
John Avatar asked Apr 10 '26 21:04

John


1 Answers

Two idioms I have seen are:

With finally

exit_code = None
try:
   do_something()
except CustomError1:
    exit_code = 1
except CustomError2:
    exit_code = 2
finally:
    if exit_code is not None:
        send_error_mail(exit_code)

With "dictionary dispatch"

try:
    do_something()
except Exception as e:
    code = {
        CustomError1: 1
        CustomError2: 2
    }.get(type(e))
    if code is None:
        raise
    send_error_email(code)

(or if you wanna go full PEP572),

    ...
    if (code := {
        CustomError1: 1
        CustomError2: 2
    }.get(type(e))) is not None:
         send_error_email(code)
    raise

If you control your exceptions however (and they are not library exceptions) - I do like @scnerd's solution too. If you don't - and want to catch ValueErrors or TypeErrors or whatever then one of these is the way to go.

like image 133
modesitt Avatar answered Apr 13 '26 11:04

modesitt



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!