Learn

Short lessons with real code you can edit and run on the page.

Errors and Exceptions in Python

Lesson 27 Python 3.14 Runs in your browser Updated
In short

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 try runs first, and the block under except ValueError runs only if a ValueError happens.
  • except ValueError as e stores the exception in e, and print(e) shows its message.
  • else runs only when the try block raised nothing, and finally runs 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.

Python
print("Start")
print(10 / 0)
print("End")
Output
Start
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print(10 / 0)
          ~~~^~~
ZeroDivisionError: division by zero

Start 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.

Python
def average(numbers):
    return sum(numbers) / len(numbers)

print(average([4, 8]))
print(average([]))
Output
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 zero

The 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.

Python
print("Start")
print("Hi"
Output
  File "main.py", line 2
    print("Hi"
         ^
SyntaxError: '(' was never closed

Start 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.

  1. Write try and a colon. Indent the code that might raise an exception below it.
  2. Add an except clause with the exception type. Line it up with try. except ValueError catches a ValueError, and its block runs only if one happens.
  3. Carry on. When either block finishes, the program continues with the first line after the whole try statement.
Python
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")
Output
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.

Python
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")
Output
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.

Python
try:
    int("abc")
except ValueError as e:
    print("Error:", e)
    print(type(e).__name__)
Output
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.

Python
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)
Output
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.

Python
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)
Output
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.

Common built-in exceptions in Python
ExceptionRaised byWhat it means
SyntaxErrorprint("Hi"The code isn't valid Python, so nothing runs
NameErrorprint(scroe)A name is used before it exists, often because of a typo
TypeError"3" + 4An operation got a value of the wrong type
ValueErrorint("abc")The type is right, but the value isn't
ZeroDivisionError10 / 0A 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
ModuleNotFoundErrorimport requestzPython can't find the module
FileNotFoundErroropen("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. except with no type catches every exception, including typos that raise NameError and the KeyboardInterrupt from pressing Ctrl+C. Name the exceptions you expect.
  • A general clause first. With except Exception above except 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.

Python
try:
    total = 10
    print(totl)
except:
    print("Something went wrong")
Output
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.

Python
a = 10
b = 0
print(a / b)
print("Done")
Output
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.

  1. 1What does this program print?

    try:
        print(int("5") + 1)
    except ValueError:
        print("not a number")
  2. 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?

  3. 3Which line of a traceback names the exception?

  4. 4When does a finally block run?

  5. 5What does this program print?

    try:
        print(score)
    except ValueError:
        print("bad value")

Frequently asked questions

What is an exception in Python?
An exception is an error that happens while a program runs, such as dividing by zero or converting "abc" to a number. If no try statement handles it, Python stops the program and prints a traceback.
What is the difference between an error and an exception in Python?
In everyday use the words mean the same thing, and most built-in exception names end in Error. The useful distinction is between syntax errors, which Python finds before the program runs, and exceptions raised while it runs, which try and except can catch.
How do I catch any exception in Python?
Use except Exception as e, which catches every ordinary exception and lets you print the message. Avoid except with no type, which also catches Ctrl+C and sys.exit(). Both forms can hide typos, so catch specific exceptions when you can.
How do I print the error message of an exception?
Name the exception with as, as in except ValueError as e, then call print(e). It prints the message the last line of a traceback would show, without the exception's type name and usually without the Did you mean hint.
Does finally always run in Python?
It runs whenever the try statement finishes, whether normally, through an exception or through a return statement. A hard stop, such as os._exit() or the program being killed from outside, skips it.
How do I raise an exception in Python?
Write raise with an exception type and a message, such as raise ValueError("price must be positive"). The function stops there, and the caller can catch the exception with try and except.
What happens when an exception is not caught?
Python stops the program and prints a traceback, which shows the chain of calls that led to the error and ends with the exception's type and message. Apart from cleanup code such as finally blocks, nothing after the failing line runs.