← All concepts

Lectures 1 and 4

Errors and how to handle them

Errors are normal. Reading the error name tells you what went wrong; try/except lets a program carry on.

The common errors

NameError — a name that was never created. TypeError — the wrong type, e.g. "A" + 1. ValueError — the right type but an impossible value, e.g. int("abc"). IndexError — a position past the end. KeyError — a dictionary key that is not there. The last line of the error message names it.

Check first, or try

An if guard checks before something can go wrong. try/except runs the risky line and, if that error happens, runs the except block instead of crashing.

text = "12x"
try:
n = int(text)
except ValueError:
n = 0
print(n)

Output

0

raise

raise stops a function with an error of your choosing — better than carrying on with bad data. The caller can catch it.

def check(seq):
if len(seq) == 0:
raise ValueError("empty sequence")
return len(seq)
try:
check("")
except ValueError as e:
print("caught:", e)

Output

caught: empty sequence

Going further

From the advanced notebook — this is what the advanced questions test.

else and finally

else runs only when the try block raised nothing; finally runs every time, error or not.

for text in ["7", "x"]:
try:
n = int(text)
except ValueError:
print(text, "is not a number")
else:
print(text, "doubled is", n * 2)
finally:
print("checked", text)

Output

7 doubled is 14
checked 7
x is not a number
checked x

Errors travel up

An error inside a function travels back to whoever called it, where an except can catch it. With several except blocks, the first matching one runs.

def first(items):
return items[0]
try:
first([])
except KeyError:
print("key")
except IndexError:
print("index")

Output

index