• Python Snacks
  • Posts
  • Python except: The Danger of Overgeneralizing Exceptions

Python except: The Danger of Overgeneralizing Exceptions

How catching every exception with ‘except’ in Python can break your code and hide critical errors.

When handling errors, you may be tempted to write your try/except statements as such:

try:
    # do thing
except:
    # handle it

While this does get the job done, overgeneralizing and trying to catch every exception is absolutely not a way to handle exceptions for a number of reasons.

As a demonstration, if we had the following code:

try:
    result = 10 / 0  # Raises ZeroDivisionError
    config = open("file.txt")  # Raises FileNotFoundError
    print(undefined_variable)  # Raises NameError
except:
    print("An error occurred.")

We see that there are 3 potential errors right off the bat: ZeroDivisionError, FileNotFoundError, and NameError. While errors are caught, it doesn’t give us any insight when it comes to debugging - all we see is a print statement saying that an error occurred.

The Issue with Overgeneralizing

The issue with overgeneralizing exceptions is that you’re handling whatever goes wrong the same way. This hides critical information and creates several issues:

  1. You hide the root cause: by lumping all exceptions together, you lose context as to why something failed.

  2. You disrupt system behavior: catching everything may trap exceptions such as KeyboardInterrupt or SystemExit; users won’t be able to stop the program gracefully and potentially interfere with shutdown processes.

  3. The code may run in an invalid or corrupted state: there’s potential the application runs without the required input file, leading to errors downstream of opening/reading the file.

The Solution to Overgeneralizing

We can write the code with the traceback in the code, which can be piped into a logfile:

import traceback
try:
    result = 10 / 0
    config = open("nonexistent_file.txt")
    print(undefined_variable)
except ZeroDivisionError:
    print("Cannot divide by zero.")
except FileNotFoundError:
    print("The file could not be found.")
except NameError as e:
    print(f"Programming error: {e}")

This is much better for a number of reasons because it catches known exceptions: ZeroDivisionError, FileNotFoundError, and NameError. With each exception, the code handles the exception appropriately.

What about a Catch-All?

You can use a catch-all statement, but you need to be careful and responsible with it. I recommend leveraging the traceback module and writing code to handle things gracefully:

import traceback

try:
    result = 10/0
except Exception as e:
    logging.critical(f"An unexpected error occurred: {e}")
    traceback.print_exception(e)
    raise # or handle it differently

That’s all - happy coding!

📧 Join the Python Snacks Newsletter! 🐍

Want even more Python-related content that’s useful? Here’s 3 reasons why you should subscribe the Python Snacks newsletter:

  1. Get Ahead in Python with bite-sized Python tips and tricks delivered straight to your inbox, like the one above.

  2. Exclusive Subscriber Perks: Receive a curated selection of up to 6 high-impact Python resources, tips, and exclusive insights with each email.

  3. Get Smarter with Python in under 5 minutes. Your next Python breakthrough could just an email away.

You can unsubscribe at any time.

Interested in starting a newsletter or a blog?

Do you have a wealth of knowledge and insights to share with the world? Starting your own newsletter or blog is an excellent way to establish yourself as an authority in your field, connect with a like-minded community, and open up new opportunities.

If TikTok, Twitter, Facebook, or other social media platforms were to get banned, you’d lose all your followers. This is why you should start a newsletter: you own your audience.

This article may contain affiliate links. Affiliate links come at no cost to you and support the costs of this blog. Should you purchase a product/service from an affiliate link, it will come at no additional cost to you.

Reply

or to participate.