0 to Infinity Lesson

Try, Except in Python

Learn Python error handling from the beginning: runtime errors, try, except, multiple exceptions, else, finally, raise, custom exceptions, and real-world safe programming.

1. Big Picture

A program can fail while running. The user may enter wrong data. A file may be missing. Internet may stop. A number may be divided by zero. Error handling helps the program survive such situations.

1 Risky Code Code that may fail
2 try Run risky code
3 except Handle error
4 else Run if no error
5 finally Always run
Main idea: try protects risky code. except decides what to do when an error happens.

Basic structure

try:
    # risky code
    pass
except:
    # what to do if error happens
    pass
Advertisement

2. What is an Error?

An error is a problem that stops or disturbs a program. In Python, many runtime problems are called exceptions.

Example: program crashes

a = 10
b = 0

print(a / b)

This program fails because division by zero is not allowed.

ZeroDivisionError: division by zero

Common Python exceptions

Exception When it happens Example
ZeroDivisionError Dividing by zero 10 / 0
ValueError Wrong value type conversion int("abc")
TypeError Wrong operation between types "5" + 2
IndexError List index does not exist items[10]
KeyError Dictionary key does not exist student["age"]
FileNotFoundError File is missing open("missing.txt")
NameError Variable is not defined print(x)
Important: Syntax errors happen before the program runs. Exceptions usually happen while the program is running.

3. Basic try and except

The try block contains risky code. The except block contains the rescue plan.

Example 1: division by zero

try:
    a = 10
    b = 0
    result = a / b
    print(result)
except:
    print("Something went wrong.")

Instead of crashing, the program prints a friendly message.

Better version: catch exact exception

try:
    a = 10
    b = 0
    result = a / b
    print(result)
except ZeroDivisionError:
    print("You cannot divide by zero.")
Good habit: Catch specific exceptions whenever possible. It makes the program clearer and safer.

Example 2: user input

try:
    age = int(input("Enter your age: "))
    print("Your age is", age)
except ValueError:
    print("Please enter a valid number.")

If the user enters abc, Python cannot convert it to an integer. So ValueError happens.

Example 3: list index

numbers = [10, 20, 30]

try:
    print(numbers[5])
except IndexError:
    print("That index does not exist.")

4. Multiple except Blocks

Different errors need different solutions. We can write more than one except block.

Example

try:
    x = int(input("Enter first number: "))
    y = int(input("Enter second number: "))

    result = x / y

    print("Result:", result)

except ValueError:
    print("Please enter numbers only.")

except ZeroDivisionError:
    print("Second number cannot be zero.")

How Python chooses the except block

Python runs the try block. If an error happens, Python searches for a matching except block.

try:
    # risky code
except ValueError:
    # handles ValueError
except ZeroDivisionError:
    # handles ZeroDivisionError

Handling multiple exceptions together

try:
    value = int(input("Enter a number: "))
    result = 100 / value
    print(result)

except (ValueError, ZeroDivisionError):
    print("Invalid input or division by zero.")

Getting the error message

try:
    number = int("abc")
except ValueError as error:
    print("Error happened:", error)

The variable error stores the original error message.

Use case: During learning or debugging, printing the real error message is helpful.

5. else and finally

Python error handling has two more useful blocks: else and finally.

5.1 else

The else block runs only if no exception happens.

try:
    number = int(input("Enter a number: "))
except ValueError:
    print("Invalid number.")
else:
    print("You entered:", number)

5.2 finally

The finally block always runs. It runs whether an error happens or not.

try:
    number = int(input("Enter a number: "))
    print(100 / number)
except ValueError:
    print("Please enter a valid number.")
except ZeroDivisionError:
    print("Number cannot be zero.")
finally:
    print("Program finished.")

Complete structure

try:
    print("Risky code runs here.")

except ValueError:
    print("Handle ValueError here.")

else:
    print("Runs only if no exception happens.")

finally:
    print("Always runs.")
Block When it runs
try First, risky code runs here.
except Runs only if matching error happens.
else Runs only if no exception happens.
finally Always runs.
Memory trick: try means attempt. except means rescue. else means success path. finally means cleanup.

6. Raising Exceptions with raise

Sometimes we want to create an error deliberately. This is done using raise.

Example: age validation

age = int(input("Enter your age: "))

if age < 0:
    raise ValueError("Age cannot be negative.")

print("Age:", age)

If the user enters a negative age, we raise an error because negative age is logically wrong.

Handling raised exception

try:
    age = int(input("Enter your age: "))

    if age < 0:
        raise ValueError("Age cannot be negative.")

    print("Age:", age)

except ValueError as error:
    print("Problem:", error)

Example: marks validation

try:
    marks = float(input("Enter marks: "))

    if marks < 0 or marks > 100:
        raise ValueError("Marks must be between 0 and 100.")

    print("Valid marks:", marks)

except ValueError as error:
    print("Invalid marks:", error)
Why use raise? It helps us stop wrong data from moving forward in the program.

7. Custom Exceptions

A custom exception is our own error class. It is useful when we want meaningful error names for our project.

Basic custom exception

class InvalidMarksError(Exception):
    pass

This creates a new exception named InvalidMarksError.

Using custom exception

class InvalidMarksError(Exception):
    pass

try:
    marks = float(input("Enter marks: "))

    if marks < 0 or marks > 100:
        raise InvalidMarksError("Marks must be between 0 and 100.")

    print("Valid marks:", marks)

except InvalidMarksError as error:
    print("Marks problem:", error)

except ValueError:
    print("Please enter a number.")

Why custom exceptions are useful

  • They make code easier to understand.
  • They separate project errors from normal Python errors.
  • They help in large applications.

8. Try Except with File Handling

File handling is one of the most common places where exceptions happen. A file may not exist. Permission may be denied. Data may be invalid.

Example: file not found

try:
    file = open("students.txt", "r")
    content = file.read()
    print(content)
    file.close()

except FileNotFoundError:
    print("The file was not found.")

Better version with finally

file = None

try:
    file = open("students.txt", "r")
    content = file.read()
    print(content)

except FileNotFoundError:
    print("The file was not found.")

finally:
    if file is not None:
        file.close()
        print("File closed.")

Best common version: use with

try:
    with open("students.txt", "r") as file:
        content = file.read()
        print(content)

except FileNotFoundError:
    print("The file was not found.")

The with statement automatically closes the file.

Good habit: Use with open(...) for file handling. Use try except to handle missing files.

9. Try Except Inside Loops

Sometimes we want to keep asking until the user gives correct input.

Example: keep asking for a number

while True:
    try:
        number = int(input("Enter a number: "))
        break
    except ValueError:
        print("Invalid input. Please try again.")

print("You entered:", number)

Example: calculator loop

while True:
    try:
        a = float(input("Enter first number: "))
        b = float(input("Enter second number: "))

        print("Division:", a / b)
        break

    except ValueError:
        print("Please enter numbers only.")

    except ZeroDivisionError:
        print("Second number cannot be zero.")

Example: list index in loop

students = ["Amit", "Ravi", "Sita"]

while True:
    try:
        index = int(input("Enter index: "))
        print("Student:", students[index])
        break

    except ValueError:
        print("Enter a number only.")

    except IndexError:
        print("That index is not available.")

10. Bad Practices and Good Practices

Bad practice 1: empty except

try:
    result = 10 / 0
except:
    pass

This hides the error completely. It becomes difficult to debug.

Better

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

Bad practice 2: catching everything without reason

try:
    number = int(input("Enter number: "))
    print(100 / number)
except:
    print("Error")

Better

try:
    number = int(input("Enter number: "))
    print(100 / number)

except ValueError:
    print("Please enter a valid number.")

except ZeroDivisionError:
    print("Number cannot be zero.")

Bad practice 3: putting too much code inside try

try:
    a = int(input("A: "))
    b = int(input("B: "))
    c = a + b
    d = c * 10
    print(d)
    print("Many more lines...")
except:
    print("Something went wrong.")

If too much code is inside try, it becomes hard to know which line caused the error.

Better habit

try:
    a = int(input("A: "))
    b = int(input("B: "))
except ValueError:
    print("Please enter numbers only.")
else:
    c = a + b
    d = c * 10
    print(d)
Professional rule: Keep the try block as small as possible. Catch specific exceptions. Do not silently hide errors.

11. Complete Mini Project: Safe Marks Calculator

This project uses input validation, try, except, else, finally, raise and a custom exception.

class InvalidMarksError(Exception):
    pass


def get_marks(subject_name):
    while True:
        try:
            marks = float(input(f"Enter marks for {subject_name}: "))

            if marks < 0 or marks > 100:
                raise InvalidMarksError("Marks must be between 0 and 100.")

        except ValueError:
            print("Please enter a numeric value.")

        except InvalidMarksError as error:
            print("Invalid marks:", error)

        else:
            return marks

        finally:
            print("Input attempt finished.\n")


try:
    python_marks = get_marks("Python")
    sql_marks = get_marks("SQL")
    pandas_marks = get_marks("Pandas")

    total = python_marks + sql_marks + pandas_marks
    average = total / 3

    print("Total:", total)
    print("Average:", average)

    if average >= 90:
        grade = "A+"
    elif average >= 75:
        grade = "A"
    elif average >= 60:
        grade = "B"
    elif average >= 40:
        grade = "C"
    else:
        grade = "Fail"

    print("Grade:", grade)

except Exception as error:
    print("Unexpected problem:", error)

finally:
    print("Program completed.")

What this project teaches

  • How to protect user input.
  • How to repeat input until valid data is entered.
  • How to raise a custom exception.
  • How to use else for successful input.
  • How to use finally for cleanup-style messages.

12. Advanced Understanding

12.1 Exception hierarchy

Python exceptions are classes. Many exceptions come from a parent class called Exception.

try:
    number = int("abc")
except Exception as error:
    print("Some exception happened:", error)

This catches many types of exceptions, but it should be used carefully.

12.2 Order of except blocks matters

try:
    number = int("abc")

except Exception:
    print("General error.")

except ValueError:
    print("Value error.")

Here, Exception catches the error first. The ValueError block will not run.

Better order

try:
    number = int("abc")

except ValueError:
    print("Value error.")

except Exception:
    print("General error.")
Rule: Put specific exceptions first and general exceptions later.

12.3 Re-raising an exception

try:
    number = int("abc")
except ValueError:
    print("Logging the error...")
    raise

raise without a new exception re-raises the current exception. This is useful when we want to log an error but still stop the program.

13. Practice in Our Python Editor

Use the embedded Python editor below to test the examples from this lesson.

Tip: If the embedded editor does not load, open it directly: Python Editor by Learn With Champak

14. Practice Tasks

  1. Write a program that divides two numbers and handles division by zero.
  2. Write a program that asks for age and handles invalid input.
  3. Write a program that asks for list index and handles IndexError.
  4. Write a program that opens a file and handles FileNotFoundError.
  5. Write a loop that keeps asking for a number until the user enters a valid number.
  6. Write a marks validation program using raise.
  7. Create a custom exception named InvalidPasswordError.
  8. Write a safe calculator using try, except, else and finally.

Self Test

What is the use of try?

try contains risky code that may raise an exception.

What is the use of except?

except handles the exception if an error happens.

When does else run?

else runs only when no exception happens in the try block.

When does finally run?

finally always runs, whether an exception happens or not.

What does raise do?

raise deliberately creates an exception.

Why should we avoid empty except blocks?

Because they hide errors and make debugging difficult.

15. Final Summary

try:
    risky code

except:
    handle error

else:
    run if no error

finally:
    always run
Final lesson: Error handling is not about hiding errors. It is about controlling errors, guiding the user, protecting data, and making programs reliable.

Professional checklist

  • Catch specific exceptions.
  • Keep try blocks small.
  • Use else for success code.
  • Use finally for cleanup.
  • Use raise for invalid business rules.
  • Use custom exceptions in larger projects.
  • Never silently hide important errors.