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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With