🌱 Junior Track 12 of 12

12. Error & Exception Handling

Write resilient Python code: `try`, `except`, `else`, `finally`, `Built-in Exceptions`, `raising exceptions`, `custom exceptions`, `exception chaining`, and avoiding overly broad `except` blocks.

👁️ Views: 0
# ==============================================================================
# JUNIOR PYTHON TRACK 12 — ERROR & EXCEPTION HANDLING
# ==============================================================================

# 1. Custom Exception Class
class InvalidAgeError(ValueError):
    """Custom exception raised when user age is out of valid bounds."""
    pass

class DatabaseConnectionError(Exception):
    """Custom exception for database operation failures."""
    pass

# 2. Function with try - except - else - finally
def safe_divide(a: float, b: float) -> float | None:
    """Demonstrates complete exception handling lifecycle."""
    result = None
    try:
        result = a / b  # May raise ZeroDivisionError
    except ZeroDivisionError as err:
        print(f"[ERROR] Division failed: {err}")
    except TypeError as err:
        print(f"[ERROR] Invalid data type provided: {err}")
    else:
        print(f"[SUCCESS] Division completed. Result = {result}")
    finally:
        print("[CLEANUP] Execution of safe_divide completed.")
    return result

# 3. Raising & Exception Chaining
def register_user(name: str, age: int):
    if age < 18:
        raise InvalidAgeError(f"User '{name}' age {age} is below minimum required 18.")
    
    try:
        # Simulating database network failure
        raise ConnectionError("Socket timed out")
    except ConnectionError as err:
        # Exception Chaining using 'from'
        raise DatabaseConnectionError("Failed to persist user in DB") from err

if __name__ == "__main__":
    print("--- Test 1: Successful Division ---")
    safe_divide(10, 2)

    print("\n--- Test 2: Handling ZeroDivisionError ---")
    safe_divide(10, 0)

    print("\n--- Test 3: Custom Exception Handling ---")
    try:
        register_user("Dilshad", 16)
    except InvalidAgeError as e:
        print(f"[CAUGHT] {e}")

⭐ Rate Track 12: Exception Handling (1 to 5 Stars)

Your rating is stored directly in the database. Average: 5.0 / 5 (1 rating)

★ ★ ★ ★ ★
🌱 Junior Track 12 Master Reference

12. Python Error & Exception Handling Reference

1️⃣ Complete Exception Control Structure

try:
    val = int("42")
except ValueError as err:
    print(f"Parsing error: {err}")
else:
    print(f"Parsed integer successfully: {val}")
finally:
    print("Completed parsing attempt.")

2️⃣ Built-in Exceptions Cheat Sheet

Exception Trigger Cause Code Example
ZeroDivisionError Division or modulo by zero. 10 / 0
ValueError Valid type but inappropriate value. int("abc")
TypeError Incompatible operation on data types. "5" + 5
KeyError Accessing missing dictionary key. user_dict["missing"]
IndexError Sequence index out of range bounds. items[99]

3️⃣ Custom Exceptions & Chaining (`from`)

Create custom domain-specific exception classes by inheriting from Exception or specialized exceptions like ValueError. Use raise NewError(...) from original_err for clean traceback chaining.

class PaymentFailedError(Exception):
    pass

try:
    process_gateway_card()
except NetworkTimeout as err:
    raise PaymentFailedError("Payment gateway failed") from err

4️⃣ Best Practices: Avoiding Overly Broad `except:`

  • Never use bare except:: Bare except catches KeyboardInterrupt and SystemExit, preventing user termination.
  • Catch specific exceptions: Always target exact exception types (`ZeroDivisionError`, `ValueError`).
  • Write informative error messages: Include contextual information (e.g., variable values, user IDs) in exception messages.
← 11. OOP 🌱 Junior Hub 13. File Handling →