Handling Errors
Stay calm when things go wrong.
Ava's program asks a customer for a quantity. The customer types, two, with letters, instead of a number. The program crashes, with a scary red message, in front of the customer. Real programs must expect trouble, like bad input and missing files, and deal with it gracefully. Python gives us exceptions.

- Real programs meet bad input
- A crash is a bad experience
- Exceptions let us react calmly
Meet some errors
Let's see common errors. Dividing by zero raises ZeroDivisionError. Converting letters to a number raises ValueError. Asking a list for an item that does not exist raises IndexError, and a dictionary raises KeyError. An error message tells you the type, and where it happened. Read it from the bottom up.
try and except
Wrap risky code in a try block. If an error happens, Python jumps to the matching except block, instead of crashing. The program carries on. Here, Ava converts the customer's text. A bad answer is caught, and a friendly message appears, instead of a crash.
text = "two"
try:
qty = int(text)
print("Quantity:", qty)
except ValueError:
print("Please type digits, like 2")
print("The program keeps running")Please type digits, like 2 The program keeps running
else, finally and several excepts
You can catch different errors differently. The else block runs only when nothing went wrong. The finally block runs always, success or failure, which is perfect for cleanup. Catch the specific errors you expect, and avoid a bare except, because it hides real bugs.
def load(name):
try:
f = open(name)
except FileNotFoundError:
print("Missing file:", name)
except PermissionError:
print("No permission")
else:
print("Loaded", name)
f.close()
finally:
print("Done with", name)
load("orders.txt")
load("nope.txt")Loaded orders.txt Done with orders.txt Missing file: nope.txt Done with nope.txt
Also uses orders.txt
fern, 2Raising your own errors
You can raise an exception yourself, when something is wrong, using the raise keyword. This is how a function refuses bad input, with a clear message. Callers can then catch it. Choose the right type, like ValueError for a bad value. Here the quantity must be positive.
def order(qty):
if qty <= 0:
raise ValueError("Quantity must be positive")
return f"Ordering {qty}"
print(order(3))
try:
print(order(-1))
except ValueError as e:
print("Rejected:", e)Ordering 3 Rejected: Quantity must be positive
A retry loop for input
Now combine loops and errors, for a robust input routine. The loop keeps asking until the answer is valid. A valid answer ends the loop with break. A bad one is caught, and the user is asked again. Customers can type anything, and the program stays calm.
while True:
text = input("How many plants? ")
try:
qty = int(text)
break
except ValueError:
print("Digits only, please.")
print("Got it:", qty)How many plants? two Digits only, please. How many plants? 2.5 Digits only, please. How many plants? 4 Got it: 4
Reading a traceback
When an error is not caught, Python prints a traceback. Read it from the bottom. The last line tells you the error type and message. The lines above show the path of calls that led there, with file names and line numbers. Look for your own file, and fix that line. A traceback is not an attack, it is a friendly map.
A safe divider
Your turn. Write a function that divides two numbers. If the second is zero, it should print, Cannot divide by zero, and return None. Use try and except. Ready? Here is one solution. The try holds the division, and the except catches ZeroDivisionError.
Write safe_divide(a, b) that returns a / b, but prints a message and returns None on division by zero.
Show hint
catch ZeroDivisionError
Show solution
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
print("Cannot divide by zero")
return None
print(safe_divide(10, 4))
print(safe_divide(1, 0))2.5 Cannot divide by zero None
Summary
Nice work. Your programs can now survive bad input. You use try and except, with else and finally, you raise your own errors, and you read tracebacks from the bottom up. Next, Ava splits her growing program into modules, and installs packages from the internet.
Key takeaways- try / except / else / finally
- Catch specific exceptions
- raise your own errors