Back to blog
← View series: python tutorials

~/blog

Error Handling

Apr 1, 20265 min readBy Mohammed Vasim
PythonProgrammingTutorialBeginner

Introduction

In this tutorial, you'll learn how to handle errors and exceptions in Python. Error handling allows your programs to deal with unexpected situations gracefully instead of crashing.

What You'll Learn

  • What are exceptions
  • The try-except block
  • Multiple except blocks
  • The else and finally clauses
  • Raising exceptions
  • Creating custom exceptions

What are Exceptions?

Exceptions are events that disrupt the normal flow of a program. They occur when something goes wrong (like dividing by zero or accessing a file that doesn't exist).

Common Exceptions

ExceptionDescription
ZeroDivisionErrorDividing by zero
TypeErrorWrong data type
ValueErrorWrong value
FileNotFoundErrorFile doesn't exist
IndexErrorList index out of range
KeyErrorDictionary key not found

Example of an Exception

python
# This will cause an error
result = 10 / 0

Output:

Traceback (most recent call last): File "main.py", line 1, in <module> result = 10 / 0 ZeroDivisionError: division by zero

The try-except Block

Handle exceptions using try-except:

python
try:
    result = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero!")

Basic Structure

python
try:
    # Code that might cause an error
    result = 10 / 0
except ZeroDivisionError:
    # What to do if error occurs
    print("Cannot divide by zero!")

Catching the Exception Message

python
try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"Error: {e}")

Multiple Except Blocks

Handle different types of exceptions:

python
try:
    num = int(input("Enter a number: "))
    result = 10 / num
except ValueError:
    print("That's not a valid number!")
except ZeroDivisionError:
    print("Cannot divide by zero!")

Catch All Exceptions

python
try:
    # Risky code
    result = 10 / 0
except Exception as e:
    print(f"Something went wrong: {e}")

⚠️ Warning: Catching all exceptions with bare except is generally discouraged as it can hide real problems.

The else Clause

The else block runs only if no exceptions occur:

python
try:
    number = int(input("Enter a number: "))
    result = 10 / number
except ValueError:
    print("Invalid input!")
except ZeroDivisionError:
    print("Cannot divide by zero!")
else:
    print(f"Result: {result}")
    print("Success! No errors occurred.")

The finally Clause

The finally block always runs, whether there's an error or not:

python
try:
    file = open("data.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("File not found!")
finally:
    print("This always runs.")
    # Good for cleanup
    if 'file' in locals():
        file.close()

When to Use finally

  • Closing files
  • Releasing resources
  • Cleaning up connections

Raising Exceptions

You can raise exceptions intentionally:

python
def divide(a, b):
    if b == 0:
        raise ValueError("Divisor cannot be zero!")
    return a / b

try:
    result = divide(10, 0)
except ValueError as e:
    print(f"Error: {e}")

Practical Examples

Example 1: Safe Division Function

python
def safe_divide(a, b):
    """Divide two numbers, handling errors"""
    try:
        result = a / b
        return result
    except ZeroDivisionError:
        return "Error: Cannot divide by zero"
    except TypeError:
        return "Error: Invalid types for division"

# Test
print(safe_divide(10, 2))    # 5.0
print(safe_divide(10, 0))    # Error: Cannot divide by zero
print(safe_divide("10", 2))  # Error: Invalid types for division

Example 2: Password Validator

python
def validate_password(password):
    """Validate password meets requirements"""
    if len(password) < 8:
        raise ValueError("Password must be at least 8 characters")
    if not any(c.isupper() for c in password):
        raise ValueError("Password must contain uppercase letter")
    if not any(c.islower() for c in password):
        raise ValueError("Password must contain lowercase letter")
    if not any(c.isdigit() for c in password):
        raise ValueError("Password must contain a number")
    return "Password is valid"

# Test
passwords = ["short", "alllowercase", "ALLUPPERCASE", "NoNumbers!", "Valid1Pass"]

for pwd in passwords:
    try:
        result = validate_password(pwd)
        print(f"'{pwd}': {result}")
    except ValueError as e:
        print(f"'{pwd}': Error - {e}")

Example 3: Reading User Input with Validation

python
def get_positive_number():
    """Get a positive number from user"""
    while True:
        try:
            number = float(input("Enter a positive number: "))
            if number <= 0:
                print("Please enter a positive number!")
                continue
            return number
        except ValueError:
            print("Invalid input. Please enter a number.")

# Use it
num = get_positive_number()
print(f"You entered: {num}")

Custom Exceptions

Create your own exception classes:

python
# Define custom exception
class InvalidAgeError(Exception):
    def __init__(self, age, message="Age must be between 0 and 150"):
        self.age = age
        self.message = message
        super().__init__(self.message)

def set_age(age):
    if age < 0 or age > 150:
        raise InvalidAgeError(age)
    return age

# Use it
try:
    set_age(200)
except InvalidAgeError as e:
    print(f"Invalid age: {e.age}")
    print(e.message)

Exception Hierarchy

python
class ValidationError(Exception):
    """Base exception for validation errors"""
    pass

class InvalidEmailError(ValidationError):
    """Raised when email is invalid"""
    pass

class InvalidPhoneError(ValidationError):
    """Raised when phone is invalid"""
    pass

def validate_email(email):
    if "@" not in email:
        raise InvalidEmailError(f"Invalid email: {email}")

def validate_phone(phone):
    if len(phone) < 10:
        raise InvalidPhoneError(f"Invalid phone: {phone}")

# Catch all validation errors
try:
    validate_email("invalid-email")
    validate_phone("123")
except ValidationError as e:
    print(f"Validation failed: {e}")

Best Practices

PracticeWhy
Be specific with exceptionsCatch only what you can handle
Don't hide exceptionsAt least log the error
Use finally for cleanupEnsure resources are released
Don't use bare exceptCatch specific exceptions
Include helpful messagesMake debugging easier

Summary

In this tutorial, you learned:

  • ✅ What are exceptions
  • ✅ The try-except block
  • ✅ Multiple except blocks
  • ✅ The else and finally clauses
  • ✅ Raising exceptions
  • ✅ Creating custom exceptions

🧑‍💻 Practice Exercise

Create a program that:

  1. Takes two numbers and an operator (+, -, *, /) as input
  2. Performs the calculation using try-except
  3. Handles: ValueError (invalid input), ZeroDivisionError, and any other errors
  4. Uses finally to always print "Calculation complete"
Click to see solution
python
def calculator():
    """Simple calculator with error handling"""
    try:
        # Get input
        num1 = float(input("Enter first number: "))
        num2 = float(input("Enter second number: "))
        operator = input("Enter operator (+, -, *, /): ")
        
        # Perform calculation
        if operator == "+":
            result = num1 + num2
        elif operator == "-":
            result = num1 - num2
        elif operator == "*":
            result = num1 * num2
        elif operator == "/":
            result = num1 / num2
        else:
            raise ValueError(f"Unknown operator: {operator}")
        
        print(f"Result: {num1} {operator} {num2} = {result}")
        
    except ValueError as e:
        print(f"Input Error: {e}")
    except ZeroDivisionError:
        print("Error: Cannot divide by zero!")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
    finally:
        print("Calculation complete.")

# Run the calculator
calculator()

Sample Output:

Enter first number: 10 Enter second number: 2 Enter operator (+, -, *, /): / Result: 10.0 / 2.0 = 5.0 Calculation complete.

What's Next

In the next tutorial, we'll learn about File Operations - how to read and write files in Python.

File Operations →

Comments (0)

No comments yet. Be the first to comment!

Leave a comment