Skip to content

Intermediate · Errors, modules and the standard library · topic 22 of 50 · 20 min

Errors and exceptions

Explanation

When something goes wrong while a program runs, Python raises an exception and prints a traceback: the error type, a message and the line where it happened. With try and except you catch a specific error and handle it instead of crashing. With raise you report your own errors with a clear message.

Two kinds of mistakes

A SyntaxError means the code is not valid Python at all, like a missing bracket. Python finds it before running anything. An exception is different: the code is valid, but something goes wrong while it runs, like dividing by zero or reading a key that is not in a dictionary.

Reading a traceback

output
Traceback (most recent call last):
  File "shop.py", line 3, in <module>
    print(total / count)
ZeroDivisionError: division by zero
A traceback. Read it from the bottom up.

Start at the last line: it names the error type (ZeroDivisionError) and gives a message (division by zero). The lines above it show the file, the line number and the exact code that failed. Most of the time, the last two lines tell you everything you need.

ErrorWhen it happensExample that causes it
SyntaxErrorThe code is not valid Pythonprint("hi"
NameErrorA name was never defined (often a typo)print(totl)
TypeErrorAn operation gets the wrong type"5" + 3
ValueErrorThe type is right but the value is notint("abc")
ZeroDivisionErrorDividing by zero10 / 0
KeyErrorA dictionary key is missingmarks["Ravi"] when there is no Ravi
IndexErrorA list position does not exist[10, 20][5]
Think of it like this: Think of paying by UPI. If the bank server is down, the app does not shut itself; it shows "Payment failed, please try again". The payment is the try. The friendly message is the except: a plan B for a problem you expected.

try and except

python
def to_number(text):
    try:
        return int(text)
    except ValueError:
        return None

print(to_number("42"))
print(to_number("forty"))
Shows 42, then None. The bad input does not crash the program.

Python runs the try block. If an exception happens there, it jumps to the matching except block. You can have several except blocks for different errors, and except ... as e gives you the error object so you can read its message.

python
def safe_divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        return "cannot divide by zero"
    except TypeError as e:
        return "bad input: " + str(e)

print(safe_divide(10, 4))
print(safe_divide(10, 0))
print(safe_divide(10, "2"))
Each error type gets its own handling.

else and finally

else runs only when the try block finished with no exception. finally runs every time, error or not; it is the place for clean-up work such as closing a file or a connection.

python
def read_age(text):
    try:
        age = int(text)
    except ValueError:
        print("Not a number:", text)
    else:
        print("Age saved:", age)
    finally:
        print("Checked", text)

read_age("21")
read_age("twenty")
else runs for "21" only; finally runs for both.

Raising your own errors

python
def withdraw(balance, amount):
    if amount <= 0:
        raise ValueError("amount must be more than 0, got " + str(amount))
    if amount > balance:
        raise ValueError("not enough balance")
    return balance - amount

try:
    withdraw(500, 800)
except ValueError as e:
    print("Error:", e)
raise stops the function and sends the error to whoever called it.
Careful: Never write a bare except: with no error type. It catches everything, including NameError from your own typos and even Ctrl+C, so real bugs hide silently. Catch the specific error you expect, such as except ValueError.
Tip: Keep the try block small: put only the line that can fail inside it. A short try block makes it clear which error you are handling, and it does not hide mistakes in other lines.

Watch the lesson

Errors and exceptions · 1/7

Errors and exceptions

Every programmer sees errors every day. In this lesson you will learn to read them and to handle them calmly.

Prefer a video by a teacher? Find free videos on “python try except exceptions tutorial” on YouTube ↗

In real life: Adding up a messy sales register

Meena keeps her shop sales in a spreadsheet. Some cells are empty and some say NA. A program that calls int() on every cell would crash on the first bad one. With try and except it adds the good numbers and simply counts the bad cells, so she can fix them later.

python
entries = ["450", "1200", "NA", "", "300"]
total = 0
skipped = 0
for item in entries:
    try:
        total += int(item)
    except ValueError:
        skipped += 1
print("Total:", total, "| skipped cells:", skipped)
Total: 1950 | skipped cells: 2

Practice (0/3 done)

Task 1 · Code · Python

Write safe_int(text, default=0) that returns int(text), but returns default when the text is not a whole number. safe_int("42") gives 42, safe_int("abc") gives 0 and safe_int("", -1) gives -1.

Task 2 · Code · Python

Write average(nums) that returns the average of a list of numbers. If the list is empty, raise ValueError with a message that contains the word "empty" (do not let a ZeroDivisionError escape).

Task 3 · Code · Python

Write stock_of(stock, item) that returns stock[item], or 0 when the item is not in the dictionary. Use try and except KeyError.

Quick quiz

Question 1

1.What does int("abc") raise?

Question 2

2.Where in a traceback do you find the error type and message?

Question 3

3.When does the else block of a try statement run?

Question 4

4.Why should you avoid a bare except: with no error type?

Question 5

5.What does "5" + 3 raise?

Read more (free)

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

← Previous: Scope: where variables live