foreach-ui logo
codeLanguages
account_treeDSA

Quick Actions

quizlock Random Quiz
trending_uplock Progress
  • 1
  • 2
  • 3
  • 4
  • quiz
Python
  • Use try/except blocks to handle errors
  • Catch specific exception types
  • Use else and finally clauses
  • Handle multiple exceptions gracefully

Try and Except

Imagine you're walking on a tightrope. Without a safety net, one mistake and it's over! But with a net below, you can take risks, and if you fall, you land safely. Try/except is your program's safety net – it lets you "try" risky code, and if something goes wrong, you're "caught" by the except block instead of crashing.

Exception handling transforms fragile programs that crash at the first sign of trouble into robust applications that handle problems gracefully.


Basic Try/Except

# Without try/except - program crashes!
number = int("hello")  # ValueError crashes the program

# With try/except - program continues!
try:
    number = int("hello")
except:
    print("That wasn't a valid number!")
    number = 0

print(f"Continuing with number = {number}")

The Flow


                    Try/Except Flow                               

                                                                  
   try:                                                          
       risky_code()                                    
                                                                 
                            
                                                                
                                                                
         NO ERROR                            ERROR OCCURS         
                                                                
                                                                
                                                                
       Skip except block              except:                    
                                         handle_error()          
                                                                
                            
                                                                 
                                                                 
                    Continue program                             
                                                                  

Catching Specific Exceptions

Don't catch everything blindly – be specific!

#  BAD: Catching everything hides real problems
try:
    result = do_something()
except:
    pass  # Silently ignores ALL errors (even bugs!)

#  GOOD: Catch specific exceptions
try:
    number = int(user_input)
except ValueError:
    print("Please enter a valid number")

Why Be Specific?

# This hides a bug in your code!
try:
    user_nme = "Alice"  # Typo: should be user_name
    print(user_name)
except:
    print("Something went wrong")  # You'll never find the typo!

# This catches only what you expect
try:
    number = int(user_input)
except ValueError:
    print("Invalid number")
# NameError from typo will still be raised (good!)

Catching Multiple Exceptions

Method 1: Multiple Except Blocks

try:
    value = my_dict[key]
    result = 10 / value
except KeyError:
    print("Key not found in dictionary")
except ZeroDivisionError:
    print("Can't divide by zero")
except TypeError:
    print("Invalid type for division")

Method 2: Tuple of Exceptions

try:
    result = 10 / int(user_input)
except (ValueError, ZeroDivisionError):
    print("Invalid input or division by zero")

Method 3: Access the Exception

try:
    result = 10 / int(user_input)
except ValueError as e:
    print(f"Value error: {e}")
except ZeroDivisionError as e:
    print(f"Math error: {e}")

The else Clause

The else block runs only if no exception occurred:

try:
    number = int(user_input)
except ValueError:
    print("Invalid number!")
else:
    # Only runs if try succeeded
    print(f"Great! Your number is {number}")
    result = number * 2

Why Use else?


                    Why Use else?                                 

                                                                  
    WITHOUT else:                                              
                                                                  
   try:                                                          
       number = int(user_input)                                  
       # This code runs in try, but exceptions here              
       # would be caught too!                                    
       result = complex_calculation(number)                      
   except ValueError:                                            
       print("Invalid")  # Catches errors from BOTH lines!      
                                                                  
    WITH else:                                                 
                                                                  
   try:                                                          
       number = int(user_input)  # Only this is protected       
   except ValueError:                                            
       print("Invalid number")                                   
   else:                                                         
       # Errors here are NOT caught (bugs should be visible!)   
       result = complex_calculation(number)                      
                                                                  

The finally Clause

The finally block ALWAYS runs, no matter what:

try:
    file = open("data.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("File not found!")
finally:
    # This ALWAYS runs
    print("Cleanup complete")

Classic Use: Resource Cleanup

file = None
try:
    file = open("data.txt", "r")
    data = file.read()
    # Process data...
except FileNotFoundError:
    print("File not found")
finally:
    if file:
        file.close()  # Always close, even if error occurred!
    print("File operation complete")

Better: Use 'with' Instead

# The 'with' statement handles cleanup automatically
try:
    with open("data.txt", "r") as file:
        data = file.read()
except FileNotFoundError:
    print("File not found")
# No finally needed - 'with' closes the file!

Complete Structure

try:
    # Code that might raise an exception
    risky_operation()
except SpecificError as e:
    # Handle specific error
    handle_error(e)
except AnotherError:
    # Handle another error type
    handle_another()
else:
    # Runs only if try succeeded (no exceptions)
    success_code()
finally:
    # ALWAYS runs (cleanup)
    cleanup()

Practical Examples

Example 1: Safe Number Input

def get_number(prompt):
    """Safely get a number from user input."""
    while True:
        try:
            return float(input(prompt))
        except ValueError:
            print("That's not a valid number. Try again.")

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

Example 2: Safe Dictionary Access

def get_user_info(users, user_id):
    """Safely get user information."""
    try:
        user = users[user_id]
        name = user["name"]
        email = user["email"]
    except KeyError as e:
        print(f"Missing data: {e}")
        return None
    else:
        return {"name": name, "email": email}

users = {
    1: {"name": "Alice", "email": "alice@example.com"},
    2: {"name": "Bob"}  # Missing email
}

print(get_user_info(users, 1))  # Works
print(get_user_info(users, 2))  # Missing email
print(get_user_info(users, 3))  # User doesn't exist

Example 3: Safe File Reading

def read_config(filename):
    """Safely read a configuration file."""
    try:
        with open(filename, "r") as file:
            content = file.read()
    except FileNotFoundError:
        print(f"Config file '{filename}' not found. Using defaults.")
        return {}
    except PermissionError:
        print(f"No permission to read '{filename}'")
        return {}
    else:
        # Parse the content only if file was read successfully
        config = {}
        for line in content.strip().split("\n"):
            if "=" in line:
                key, value = line.split("=", 1)
                config[key.strip()] = value.strip()
        return config

config = read_config("settings.txt")

Common Mistakes

1. Catching Too Broadly

#  BAD: Hides all errors, including bugs
try:
    result = calculate(x)
except:
    pass

#  GOOD: Catch specific exceptions
try:
    result = calculate(x)
except ValueError:
    result = default_value

2. Empty Except Blocks

#  BAD: Silently ignores errors
try:
    data = load_data()
except Exception:
    pass  # What happened? No one knows!

#  GOOD: At least log the error
try:
    data = load_data()
except Exception as e:
    print(f"Warning: Could not load data: {e}")
    data = []

Key Takeaways


                   Remember These Points                          

                                                                  
   try: Contains code that might fail                          
     except: Handles the error                                    
                                                                  
   Be SPECIFIC about which exceptions to catch                 
     except ValueError: instead of bare except:                   
                                                                  
   else: Runs only if try succeeded                            
     Good for code that should only run on success                
                                                                  
   finally: ALWAYS runs (even after return!)                   
     Use for cleanup (closing files, connections)                 
                                                                  
   Access exception: except ValueError as e:                   
                                                                  

What's Next?

You can now catch errors! But what if YOU want to signal that something went wrong? In the next lesson, we'll learn raising exceptions – how to create and throw your own errors.

© 2026 forEach. All rights reserved.

Privacy Policy•Terms of Service