📝 Python

Try/Except: Taming Errors ❗

0
Author
04e5cc8b-58ac-4bdc-bdee-661bbb
📅
Published
03.04.2026
⏱️
Reading time
6 min
👁️
Views
98
🌱
Level
Beginner

Goal: Learn to handle exceptions and write robust programs.


🤔 Why Do Programs Crash?

Imagine you’re writing a calculator. The user enters 10 / 0. The program CRASHES! 💥

number = 10 / 0  # ZeroDivisionError: division by zero

Problem: Python doesn’t know what to do when something goes wrong.

Solution: Teach the program to handle errors using try/except.


🛡️ Basic try/except Syntax

try:
    # Risky code that might fail
    result = 10 / 0
except:
    # What to do if an error occurs
    print("An error occurred!")

How it works:
1. Python tries (try) to execute the code
2. If an error occurs, it jumps to the except block
3. The program doesn’t crash — it keeps running!


🎯 Catching Specific Errors

Bad: Catching every possible error blindly

try:
    result = int("abc")
except:
    print("Error!")  # Which error? No idea!

Good: Catching a specific error type

try:
    result = int("abc")
except ValueError:
    print("That's not a number! Please enter a number.")

Why this matters:
- Different errors call for different responses
- Easier to understand what went wrong
- Code becomes more reliable


📋 Common Exception Types

1. ValueError — invalid value

try:
    age = int("twenty")  # Can't convert text to a number
except ValueError:
    print("Please enter a number as digits!")

When it occurs:
- int("abc") — converting invalid text
- float("xyz") — same for floats


2. ZeroDivisionError — division by zero

try:
    result = 100 / 0
except ZeroDivisionError:
    print("You can't divide by zero!")

When it occurs:
- Any division by zero
- Mathematical operations with a zero denominator


3. FileNotFoundError — file not found

try:
    with open("missing.txt", "r") as f:
        data = f.read()
except FileNotFoundError:
    print("File not found! Check the path.")

When it occurs:
- Trying to open a non-existent file
- Wrong file path


4. TypeError — wrong data type

try:
    result = "5" + 10  # Can't add a string and a number
except TypeError:
    print("Incompatible data types!")

When it occurs:
- Operations between incompatible types
- Calling a function with wrong argument types


5. KeyError — key not found in dictionary

try:
    user = {"name": "Alice"}
    age = user["age"]  # Key "age" doesn't exist!
except KeyError:
    print("That key doesn't exist in the dictionary!")

When it occurs:
- Accessing a non-existent dictionary key
- Trying to retrieve a value for a missing key


6. IndexError — index out of range

try:
    numbers = [1, 2, 3]
    print(numbers[10])  # Index 10 doesn't exist!
except IndexError:
    print("Index is out of range!")

When it occurs:
- Accessing a non-existent list index
- Trying to retrieve an element beyond the list bounds


🎭 Multiple except Blocks

Handle different errors differently:

try:
    age = int(input("Your age: "))
    result = 100 / age
except ValueError:
    print("Please enter a number!")
except ZeroDivisionError:
    print("Age can't be zero!")

Order matters:
- Specific exceptions first
- More general ones after (if needed)


📦 Getting Error Details

try:
    number = int("abc")
except ValueError as e:
    print(f"Error: {e}")
    # Output: Error: invalid literal for int() with base 10: 'abc'

The variable e:
- Contains the exception object
- Lets you print details
- Useful for logging


🧹 The finally Block — Always Runs

try:
    file = open("data.txt", "r")
    data = file.read()
except FileNotFoundError:
    print("File not found!")
finally:
    print("This code always runs")
    # Close the file, release resources, etc.

When to use finally:
- Closing files
- Releasing resources
- Cleaning up temporary data
- Code that must run regardless of errors

Example with files:

file = None
try:
    file = open("data.txt", "r")
    data = file.read()
except FileNotFoundError:
    print("File not found!")
finally:
    if file:
        file.close()  # Guaranteed to close the file

Note: With with open(), finally is unnecessary — the file closes automatically!


🔄 The else Block — No Errors Occurred

try:
    age = int(input("Age: "))
except ValueError:
    print("That's not a number!")
else:
    print(f"Your age: {age}")
    # Executes only if NO error occurred

When to use else:
- Code that should run only on success
- Logic that depends on a successful try


⚠️ When NOT to Use try/except

❌ Bad: Hiding problems

try:
    hacky_code_here()
except:
    pass  # Silently ignore all errors — BAD!

Why it’s bad:
- Hides real bugs in the code
- Makes debugging very hard
- Can lead to unpredictable behavior

❌ Bad: Replacing explicit checks

# Bad
try:
    if user["age"] > 18:
        print("Adult")
except KeyError:
    print("Age unknown")

# Good
if "age" in user and user["age"] > 18:
    print("Adult")
else:
    print("Age unknown")

Rule: If you can check a condition before an error occurs, do that instead!


✅ When to Use try/except

✅ File I/O

try:
    with open("data.txt", "r") as f:
        data = f.read()
except FileNotFoundError:
    print("Creating a new file...")
    with open("data.txt", "w") as f:
        f.write("Initial data")

✅ User Input

while True:
    try:
        age = int(input("Enter age: "))
        break  # Success! Exit the loop
    except ValueError:
        print("That's not a number! Please try again.")

✅ Network/API Calls

try:
    response = api.get_data()
except ConnectionError:
    print("No internet connection!")
except TimeoutError:
    print("Server is not responding!")

✅ Data Conversion

try:
    data = json.loads(json_string)
except json.JSONDecodeError:
    print("Invalid JSON!")

🎯 Pattern: Safe Input

Task: Keep prompting for a number until the user enters a valid one.

def get_number(prompt):
    """Safely read a number with retry on bad input."""
    while True:
        try:
            value = int(input(prompt))
            return value  # Success! Return the number
        except ValueError:
            print("Error! Please enter an integer.")

# Usage
age = get_number("Enter your age: ")
print(f"You are {age} years old")

Benefits:
- Program doesn’t crash
- User gets clear feedback
- Input can be retried


🎯 Pattern: Default Value

def get_setting(key, default=None):
    """Retrieve a setting or return a default value."""
    try:
        with open("settings.json", "r") as f:
            settings = json.load(f)
            return settings[key]
    except (FileNotFoundError, KeyError):
        return default

# Usage
theme = get_setting("theme", "dark")  # Returns "dark" if file doesn't exist

🎯 Pattern: Retry

def save_data(data, attempts=3):
    """Save data with retries."""
    for attempt in range(attempts):
        try:
            with open("data.json", "w") as f:
                json.dump(data, f)
            print("Data saved!")
            return True
        except IOError:
            print(f"Attempt {attempt + 1} failed...")

    print("Failed to save data!")
    return False

⚡ Best Practices

✅ Do:

  1. Catch specific exceptions (except ValueError:)
  2. Give clear error messages (“Enter a number between 1 and 100”)
  3. Log errors (print or write to a file)
  4. Use finally for resource cleanup
  5. Keep the try block narrow (only the risky code)

❌ Don’t:

  1. Avoid bare except: (without specifying the error type)
  2. Don’t silently swallow errors (except: pass)
  3. Don’t make try too wide (wrapping all your code in try)
  4. Don’t hide bugs (using try/except instead of fixing the root cause)

📝 Example: Bank Account Validation

class BankAccount:
    def __init__(self, balance=0):
        self.balance = balance

    def deposit(self, amount):
        """Deposit funds."""
        try:
            amount = float(amount)  # Convert to a number

            if amount <= 0:
                print("Amount must be positive!")
                return False

            self.balance += amount
            print(f"Deposited: {amount}. Balance: {self.balance}.")
            return True

        except ValueError:
            print("Please enter a number!")
            return False

    def withdraw(self, amount):
        """Withdraw funds."""
        try:
            amount = float(amount)

            if amount <= 0:
                print("Amount must be positive!")
                return False

            if amount > self.balance:
                print("Insufficient funds!")
                return False

            self.balance -= amount
            print(f"Withdrawn: {amount}. Remaining: {self.balance}.")
            return True

        except ValueError:
            print("Please enter a number!")
            return False

# Usage
account = BankAccount(1000)
account.deposit("500")      # OK
account.deposit("abc")      # Validation error
account.withdraw("2000")    # Insufficient funds
account.withdraw("300")     # OK

🎓 Summary

try/except:
- ✅ Prevents the program from crashing
- ✅ Handles unpredictable situations
- ✅ Improves user experience
- ✅ Makes code more reliable

Golden rule: Use try/except where you can’t predict the outcome (user input, files, network), but don’t use it instead of regular checks!

Structure:

try:
    # Risky code
    ...
except SpecificError:
    # Handle a specific error
    ...
except AnotherError as e:
    # Handle another error
    print(f"Error: {e}")
else:
    # Executes if no error occurred
    ...
finally:
    # Always executes
    ...

Now your code doesn’t crash — it handles errors gracefully! 🛡️

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

Setting Up Your Environment: Python, pip, and VS …

Before writing code locally, you need to set up three tools: Python, pip, and VS...

📅 04.06.2026 👁️ 17
📝

The datetime Module: Working with Dates and Times

datetime is Python's standard module for working with dates and times. It's part of the...

📅 08.05.2026 👁️ 67
📝

.env Files and Environment Variables: Keeping Sec…

Imagine you wrote a program with an API key hardcoded in the source and pushed...

📅 08.05.2026 👁️ 76

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!