Ojasa Mirai

Ojasa Mirai

Python

Loading...

Learning Level

🟢 Beginner🔵 Advanced
Exceptions OverviewException TypesTry-Except BlocksRaising ExceptionsCustom ExceptionsMultiple ExceptionsFinally & CleanupDebugging TechniquesLogging Best Practices
Python/Error Handling/Try Except Blocks

🛡️ Try-Except Blocks — The Foundation of Error Handling

Learn the basic pattern for catching and handling exceptions without crashing your program.


📌 Basic Try-Except Structure

The `try-except` block is the simplest way to handle exceptions:

# Basic pattern
try:
    # Code that might raise an exception
    risky_operation()
except ExceptionType:
    # Code that runs if exception occurs
    handle_error()

# Example
try:
    age = int("not a number")
except ValueError:
    print("Please enter a valid number!")

# Program continues after except block
print("Program still running!")

🎯 Catching Specific Exceptions

Catch only the exceptions you expect and can handle:

# Wrong: catching generic Exception
try:
    file = open("data.txt")
    lines = file.readlines()
    count = int(lines[0])  # Could be ValueError, IndexError, or FileNotFoundError
except Exception:
    print("Something went wrong!")  # Too vague!

# Better: catch specific exceptions
try:
    file = open("data.txt")
    lines = file.readlines()
    count = int(lines[0])
except FileNotFoundError:
    print("File doesn't exist!")
except IndexError:
    print("File is empty!")
except ValueError:
    print("First line isn't a number!")

# Best: handle each scenario appropriately
try:
    with open("data.txt") as file:
        first_line = file.readline()
        if not first_line:
            print("File is empty. Using default.")
        else:
            count = int(first_line)
            print(f"Count: {count}")
except FileNotFoundError:
    print("Creating new file...")
    with open("data.txt", "w") as f:
        f.write("0")
except ValueError:
    print("Invalid number format. Using default: 0")

📥 Accessing Exception Information

Use `as` to get the exception object with details:

# Access exception details
try:
    numbers = [1, 2, 3]
    print(numbers[10])
except IndexError as e:
    print(f"Error type: {type(e).__name__}")
    print(f"Error message: {e}")
    print(f"Error args: {e.args}")

# Output:
# Error type: IndexError
# Error message: list index out of range
# Error args: ('list index out of range',)

# Practical example: validating user input
def get_positive_integer(prompt):
    try:
        value = int(input(prompt))
        if value <= 0:
            print("Please enter a positive number!")
            return None
        return value
    except ValueError as e:
        print(f"Invalid input: {e}")
        return None

# Test it
age = get_positive_integer("Enter your age: ")

🔄 Multiple Except Blocks

Handle different exceptions with different logic:

# Processing a data file
def process_user_file(filename):
    try:
        with open(filename) as f:
            data = json.load(f)
            age = int(data["age"])
            email = data["email"]

            return {
                "age": age,
                "email": email,
                "valid": True
            }

    except FileNotFoundError:
        print(f"File '{filename}' not found. Creating default...")
        return {"valid": False, "error": "file_missing"}

    except json.JSONDecodeError:
        print(f"'{filename}' contains invalid JSON.")
        return {"valid": False, "error": "invalid_json"}

    except KeyError as e:
        print(f"Missing required field: {e}")
        return {"valid": False, "error": "missing_field"}

    except ValueError:
        print("Age field must be a number!")
        return {"valid": False, "error": "invalid_age"}

# Test with different scenarios
result = process_user_file("user.json")
print(result)

🐛 Catching Multiple Exceptions in One Block

When you want the same handling for multiple exceptions:

# Option 1: Tuple of exceptions
try:
    user_input = input("Enter a number: ")
    number = int(user_input)
    result = 100 / number
    print(f"Result: {result}")
except (ValueError, ZeroDivisionError):
    print("Invalid input or cannot divide by zero!")

# Option 2: Catch parent exception
try:
    user_input = input("Enter a number: ")
    number = int(user_input)
    result = 100 / number
except ArithmeticError:  # Parent of ZeroDivisionError
    print("Math error!")
except ValueError:
    print("Invalid number format!")

# Option 3: Handle and re-examine
try:
    data = {"name": "Alice", "age": 25}
    age = int(data.get("age", "0"))
except (ValueError, TypeError):
    print("Age must be a valid number!")
    age = 0

🎨 Practical Examples

# Example 1: Safe list access
def get_item_safe(items, index, default=None):
    try:
        return items[index]
    except (IndexError, TypeError):
        print(f"Cannot access index {index}")
        return default

print(get_item_safe([1, 2, 3], 1))    # Returns 2
print(get_item_safe([1, 2, 3], 10))   # Returns None
print(get_item_safe("abc", 0))        # Returns 'a' (strings are indexable)

# Example 2: Safe dictionary access (though dict.get() is better)
def get_value_safe(dictionary, key, default=None):
    try:
        return dictionary[key]
    except KeyError:
        print(f"Key '{key}' not found")
        return default

user = {"name": "Bob", "age": 30}
print(get_value_safe(user, "name"))     # Returns "Bob"
print(get_value_safe(user, "email"))    # Returns None

# Example 3: API call with error handling
def fetch_data(url):
    try:
        response = requests.get(url, timeout=5)
        return response.json()
    except requests.ConnectionError:
        print("Network error. Check your connection.")
        return None
    except requests.Timeout:
        print("Request timed out. Server took too long.")
        return None
    except ValueError:
        print("Response isn't valid JSON.")
        return None

# Example 4: Safe type conversion
def to_integer(value):
    try:
        return int(value)
    except (ValueError, TypeError):
        print(f"Cannot convert {value} to integer")
        return None

print(to_integer("42"))      # Returns 42
print(to_integer(3.14))      # Returns 3
print(to_integer("abc"))     # Returns None

❌ Common Mistakes to Avoid

# ❌ Mistake 1: Too broad exception catching
try:
    result = 10 / 0
except:  # Catches EVERYTHING, even system exits!
    print("Error occurred")

# ✅ Better: catch specific exceptions
try:
    result = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero!")

# ❌ Mistake 2: Ignoring exceptions silently
try:
    file = open("important.txt")
except:
    pass  # Silent failure - you won't know it failed!

# ✅ Better: log or handle appropriately
try:
    file = open("important.txt")
except FileNotFoundError:
    print("File not found. Please check the path.")
    file = None

# ❌ Mistake 3: Not using exception information
try:
    number = int("abc")
except ValueError as e:
    print("Error!")  # What error? Can't tell!

# ✅ Better: use the exception info
try:
    number = int("abc")
except ValueError as e:
    print(f"Cannot convert to integer: {e}")

🎯 Key Takeaways

  • ✅ Use `try` block for code that might fail
  • ✅ Use `except` block to handle specific exceptions
  • ✅ Catch specific exceptions, not generic `Exception`
  • ✅ Use `as` to access exception details
  • ✅ Multiple `except` blocks handle different errors differently
  • ✅ Multiple exceptions can share one `except` block with tuple syntax


Resources

Python Docs

Ojasa Mirai

Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.

Learn Deep • Build Real • Verify Skills • Launch Forward

Courses

PythonFastapiReactJSCloud

© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn