Errors and Exceptions in Python
An exception is an error that happens while a program is running. If nothing handles it, Python stops and prints a traceback that names the error and the line. A try statement with an except clause catches the exception, so the program can keep going.
Key facts
- An uncaught exception stops the program and prints a traceback. Its last line names the exception and gives the message.
- Code under
tryruns first, and the block underexcept ValueErrorruns only if aValueErrorhappens. except ValueError as estores the exception ine, andprint(e)shows its message.elseruns only when the try block raised nothing, andfinallyruns whether or not an exception happened.raise ValueError("message")raises an exception on purpose.
What is an exception in Python?
An exception is an error that happens while a program is running. When one occurs and nothing handles it, Python stops the program at that line and prints a report called a traceback.
print("Start")
print(10 / 0)
print("End")Start
Traceback (most recent call last):
File "main.py", line 2, in <module>
print(10 / 0)
~~~^~~
ZeroDivisionError: division by zeroStart is printed, because the first line ran normally. The division fails, Python raises a ZeroDivisionError, and End never prints. Each kind of error has its own exception type, so int("abc") raises ValueError and reading a missing dictionary key raises KeyError.
How do I read a Python traceback?
Read a traceback from the bottom up. The last line names the exception and says what went wrong, and the lines above it show where, with the most recent call last.
def average(numbers):
return sum(numbers) / len(numbers)
print(average([4, 8]))
print(average([]))6.0
Traceback (most recent call last):
File "main.py", line 5, in <module>
print(average([]))
~~~~~~~^^^^
File "main.py", line 2, in average
return sum(numbers) / len(numbers)
~~~~~~~~~~~~~^~~~~~~~~~~~~~
ZeroDivisionError: division by zeroThe last line says a division by zero happened. The three lines above it show where, on line 2 inside average(), and the three above those show the call on line 5 that led there. Each group is called a frame, and its ^ and ~ marks point at the part that was running.
The real bug is the empty list passed on line 5, even though the error was raised on line 2. Read every frame, because the line that raised the error isn't always the line to fix.
What is the difference between a syntax error and an exception?
A syntax error is found before the program starts, and an exception happens while it runs. Python checks the whole file first, so one syntax error means no line runs at all, not even the ones above it.
print("Start")
print("Hi" File "main.py", line 2
print("Hi"
^
SyntaxError: '(' was never closedStart never appears, which is how you tell the two apart. SyntaxError is still an exception type, but Python raises it for the whole file before any line runs, so no try statement in that file can catch it.
The Python validator tool checks a file for syntax errors without running it.
How do I use try and except in Python?
Put the code that might fail under try and the code that handles the failure under except.
- Write try and a colon. Indent the code that might raise an exception below it.
- Add an except clause with the exception type. Line it up with
try.except ValueErrorcatches aValueError, and its block runs only if one happens. - Carry on. When either block finishes, the program continues with the first line after the whole try statement.
text = input("Enter a whole number: ")
try:
number = int(text)
print("Double is", number * 2)
except ValueError:
print("That is not a whole number.")
print("Program continues")Enter a whole number: That is not a whole number. Program continues
The input box holds abc, so int(text) raises ValueError, and Python skips the rest of the try block and runs the matching except block. Any lines before the error have already run. Change abc in the input box to a whole number such as 7 and run it again to see the other path.
How do I catch more than one exception?
Add one except clause for each exception type, or list several types in parentheses in one clause. Python checks the clauses from top to bottom and runs the first one that matches.
values = ["10", "zero", "0"]
for value in values:
try:
print(100 / int(value))
except ValueError:
print(value, "is not a number")
except ZeroDivisionError:
print("cannot divide by zero")10.0 zero is not a number cannot divide by zero
Each pass through the loop has its own try, so one bad value doesn't stop the rest. To handle two exceptions in one clause, write except (ValueError, ZeroDivisionError).
Python 3.14 also accepts the types without parentheses, as long as the clause doesn't use as, which the next section covers. Earlier Python 3 versions reject that form.
How do I get the error message from an exception?
Add as and a name after the exception type, and Python stores the exception in that variable. Printing it shows the message the traceback's last line would show, without the type name and usually without the "Did you mean" hint.
try:
int("abc")
except ValueError as e:
print("Error:", e)
print(type(e).__name__)Error: invalid literal for int() with base 10: 'abc' ValueError
type(e).__name__ gives the exception's type as text. e is the usual name, short for error or exception, and it exists only inside the except block, because Python deletes it when the block ends. Store the message in another variable if you need it later.
What do else and finally do in a try statement?
else runs only when the try block raised no exception, and finally runs whether or not an exception happened. Use finally for cleanup that has to happen either way, such as closing a file.
def divide(a, b):
try:
result = a / b
except ZeroDivisionError:
print("cannot divide by zero")
else:
print("result:", result)
finally:
print("done")
divide(10, 2)
divide(1, 0)result: 5.0 done cannot divide by zero done
The first call succeeds, so else prints the result. The second fails, so except runs instead, and finally runs in both calls. The clauses must appear in the order try, except, else, finally.
Code in else could sit at the end of the try block instead. Keeping it in else means the except clause can't catch an error from that code by mistake.
How do I raise an exception in Python?
Write raise followed by an exception type and a message, as in raise ValueError("age cannot be negative"). The function stops there, and the caller can catch the exception with try and except.
def set_age(age):
if age < 0:
raise ValueError("age cannot be negative")
return age
try:
set_age(-5)
except ValueError as e:
print("Rejected:", e)Rejected: age cannot be negative
Raise an exception when a function gets a value it can't work with, instead of returning a special value the caller might not check. Pick the built-in type that fits, such as ValueError for a bad value or TypeError for the wrong type.
Inside an except block, raise on its own raises the caught exception again. You can react to an error, for example by printing a note, and still let it stop the program.
What are the common built-in exceptions in Python?
Python has dozens of built-in exceptions, and the table lists ten common ones with code that raises each.
| Exception | Raised by | What it means |
|---|---|---|
SyntaxError | print("Hi" | The code isn't valid Python, so nothing runs |
NameError | print(scroe) | A name is used before it exists, often because of a typo |
TypeError | "3" + 4 | An operation got a value of the wrong type |
ValueError | int("abc") | The type is right, but the value isn't |
ZeroDivisionError | 10 / 0 | A division or modulo by zero |
IndexError | [1, 2][5] | An index is out of range for a list, string or tuple |
KeyError | {"a": 1}["b"] | A dictionary has no such key |
AttributeError | "hi".push("!") | The value has no attribute or method by that name |
ModuleNotFoundError | import requestz | Python can't find the module |
FileNotFoundError | open("notes.txt") | open() was given a file that doesn't exist |
Every exception in the table is a subtype of Exception, the way bool is a subtype of int, so except Exception catches any of them raised while the program runs. The one case it misses is a SyntaxError in your own file, because that stops the file before any try statement runs.
The built-in exceptions page in the documentation lists the rest.
Common mistakes with exceptions in Python
These four habits make errors harder to find, because each one hides the real problem or catches the wrong exception.
- A bare except.
exceptwith no type catches every exception, including typos that raiseNameErrorand theKeyboardInterruptfrom pressing Ctrl+C. Name the exceptions you expect. - A general clause first. With
except Exceptionaboveexcept ValueError, the second clause never runs, because Python uses the first clause that matches. Put specific exceptions first. - Too much code in the try block. A long try block can catch an error from a line you never meant to protect. Keep only the line that can fail inside try, and move the lines that need its result to
else. - An except block with only pass. It throws the error away without a trace. If you mean to ignore an error, name that one exception instead of using a bare except.
The program below hides a typo behind a bare except. Change except to except ValueError and run it again to see the real error.
try:
total = 10
print(totl)
except:
print("Something went wrong")Something went wrong
Exercise
Put the print(a / b) line inside try, and add an except ZeroDivisionError block that prints cannot divide by zero, so the program prints that and then Done. The starter stops with a traceback before it reaches Done.
a = 10
b = 0
print(a / b)
print("Done")
cannot divide by zero Done
Show the solution
a = 10
b = 0
try:
print(a / b)
except ZeroDivisionError:
print("cannot divide by zero")
print("Done")
Quiz
This quiz has 5 questions. Pick an answer to see why it is right or wrong.
-
1What does this program print?
try: print(int("5") + 1) except ValueError: print("not a number")int("5") succeeds and gives the number 5, so the try block prints 6 and the except block is skipped. The except block runs only when a ValueError happens.
-
2A try statement has except, else and finally clauses. The try block raises an exception that the except clause catches. Which blocks run, and in what order?
The try block runs until the error, the matching except block handles it, and finally runs last. The else block runs only when the try block raised nothing.
-
3Which line of a traceback names the exception?
The last line gives the exception type and its message. The lines above it show where the error happened, with the most recent call last.
-
4When does a finally block run?
finally runs last, after the try block and any except or else block, whether the code succeeded or failed, which makes it the place for cleanup. else is the clause that runs only when nothing went wrong.
-
5What does this program print?
try: print(score) except ValueError: print("bad value")score was never defined, so the try block raises NameError, which the ValueError clause does not match. The exception goes uncaught and the program stops with a traceback.























