ShareYourGroupShareYourGroupPython

Lesson 19 of 21 · about 8 minutes with the exercises

Errors and try/except

Some errors are your own typing mistakes, and the cure is to fix the code. Others are not your fault at all: the user types "ten" where a number is needed, a file has been deleted, the divisor turns out to be zero. A good program expects these and handles them. Python's tool for this is try and except.

What an error looks like

When Python cannot carry out a line, it raises an exception. If nothing handles it, the program stops and prints a traceback.

number = int("ten")
print("This line never runs")

What Python says

Traceback (most recent call last):
  File "example.py", line 1, in <module>
    number = int("ten")
ValueError: invalid literal for int() with base 10: 'ten'

The last line of the traceback has two parts: the type of the exception, here ValueError, and a message. The type is what you will catch.

Catching an error

Put the risky lines in a try block. Put what to do if they fail in an except block.

text = "ten"
try:
    number = int(text)
    print("Twice that is", number * 2)
except ValueError:
    print("That is not a whole number.")
print("The program carries on.")

Output

That is not a whole number.
The program carries on.

Python tries the first block. The moment a line raises a ValueError, it jumps to the except block, skipping the rest of the try. If no error happens, the except block is skipped.

Asking until the answer is good

Combine try with the while True loop from lesson 9. The person here typed abc, then 4.5, then 12.

while True:
    try:
        age = int(input("Your age? "))
        break
    except ValueError:
        print("Please type a whole number.")
print("Age:", age)

Output

Your age? abc
Please type a whole number.
Your age? 4.5
Please type a whole number.
Your age? 12
Age: 12

The break is reached only when int succeeds. This pattern belongs in every program that asks for a number.

Different errors, different answers

One try can have several except blocks. Python uses the first one that matches.

def divide(a, b):
    try:
        return int(a) / int(b)
    except ValueError:
        return "Both values must be numbers."
    except ZeroDivisionError:
        return "Cannot divide by zero."

print(divide("10", "4"))
print(divide("10", "x"))
print(divide("10", "0"))

Output

2.5
Both values must be numbers.
Cannot divide by zero.

To treat two kinds the same way, list them in brackets: except (ValueError, ZeroDivisionError):.

Reading the error message

Add as e to get the exception itself, which holds the message.

try:
    marks = [70, 80]
    print(marks[5])
except IndexError as e:
    print("Problem:", e)

Output

Problem: list index out of range

Common exception types

ExceptionRaised when
ValueErrorthe type is right but the value is not, such as int("ten")
TypeErrorthe type is wrong, such as "5" + 5
ZeroDivisionErroryou divide by zero
IndexErrora list position does not exist
KeyErrora dictionary key does not exist
FileNotFoundErrorthe file to read is not there
NameErrora name has no value yet

Each one has its own page in the errors section.

else and finally

Two more optional blocks complete the picture.

def read_number(text):
    try:
        value = float(text)
    except ValueError:
        print("Not a number:", text)
    else:
        print("Got", value)
    finally:
        print("Checked", repr(text))

read_number("3.5")
read_number("abc")

Output

Got 3.5
Checked '3.5'
Not a number: abc
Checked 'abc'

A missing file

try:
    with open("settings.txt", encoding="utf-8") as f:
        settings = f.read()
except FileNotFoundError:
    settings = "default"
    print("No settings file found. Using defaults.")
print(settings)

Output

No settings file found. Using defaults.
default

This is a natural use: try the normal thing, and fall back to something sensible when it is not possible.

Do not catch everything

It is tempting to write a bare except: that catches every error. Do not. It also hides your own bugs, such as a misspelt variable name, and the program fails silently in ways that take hours to find. Catch the specific exceptions you expect and let the rest stop the program, so that you see them.

Also keep the try block small. Put in it only the lines that can raise the error you are handling.

Raising your own errors

Your functions can raise exceptions too, with the keyword raise. Do this when a function is given a value it cannot sensibly work with.

def percentage(marks, total):
    if total <= 0:
        raise ValueError("total must be more than zero")
    return marks / total * 100

try:
    print(percentage(45, 0))
except ValueError as e:
    print("Error:", e)

Output

Error: total must be more than zero

Raising an error is better than returning a strange value such as -1, because the caller cannot ignore it by accident.

Check first, or try?

For simple cases a plain if is clearer: if b != 0: before dividing. For anything where checking in advance is hard, such as whether a string is a valid number or whether a file can be opened, try is the Python way.

Try it yourself

Exercise 1. Convert the string "12a" to an integer inside a try. If it fails, print Invalid number.

Show one answer
try:
    n = int("12a")
    print(n)
except ValueError:
    print("Invalid number")

Output

Invalid number

Exercise 2. Write a function safe_divide(a, b) that returns the result, or None if b is zero. Test both cases.

Show one answer
def safe_divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        return None

print(safe_divide(10, 4), safe_divide(10, 0))

Output

2.5 None

Exercise 3. A dictionary holds {"tea": 12, "lassi": 40}. Look up "coffee" inside a try and print Not on the menu if the key is missing.

Show one answer
menu = {"tea": 12, "lassi": 40}
try:
    print(menu["coffee"])
except KeyError:
    print("Not on the menu")

Output

Not on the menu

Examples on this page were run with Python 3.14 on 12 November 2026. The output shown is the real output.

This is an independent learning site. It is not connected with or approved by the Python Software Foundation. "Python" is a trademark of the Python Software Foundation and is used here only to name the language.