Python Try...Except
Core Python Errors and Exceptions

Python Exceptions: try, except, else and finally

1Python Try...Except: overview

An exception is Python's signal that something went wrong while the program was running. If nothing handles it the program stops, but a try/except block lets you catch it and recover.

GoalBy the end you can read a traceback, catch specific exceptions with try/except, use else and finally, raise exceptions yourself and define a simple custom exception class.

Before this lesson: Python if, elif and else, Python Functions

2Python Try...Except: diagram

Python Exceptions: try, except, else and finallytry: qty = int(text)risky codetext is "two"ValueError raisedrest of try is skippedjumpexcept ValueError:type matches?yesqty = 0recover with a defaultprogram continues
When a line inside try raises an exception, Python skips the rest of the try block, finds the first matching except, runs it and then carries on instead of crashing. If nothing in try fails, the except block never runs.

3Python Try...Except: explained step by step

Some problems only show up while a program is running: turning "abc" into a number, dividing by zero, reading a file that isn't there. Python reports each one by raising an exception, an object that describes what went wrong. If nothing handles it, the program stops and prints a traceback.

Reading a traceback

Traceback (most recent call last):
  File "main.py", line 4, in <module>
    print(average([]))
          ~~~~~~~^^^^
  File "main.py", line 2, in average
    return sum(numbers) / len(numbers)
           ~~~~~~~~~~~~~^~~~~~~~~~~~~~
ZeroDivisionError: division by zero

Read it from the bottom up. The last line says what happened: the exception type (ZeroDivisionError) and a message. The lines above say where: each File ..., line ... entry is one step in the chain of function calls, with the most recent call at the bottom. Here line 4 called average([]), and line 2 inside it divided by len([]), which is 0. The ^ and ~ markers point at the exact expression that failed.

Catching an exception with try/except

Put the risky code in a try block and say what to do instead in an except block. If the try block succeeds, the except block is skipped.

Python
def to_number(text):
    try:
        return int(text)
    except ValueError:
        print(f"{text!r} is not a whole number, using 0")
        return 0

print(to_number("42"))
print(to_number("forty"))

Always name the exception you expect. A bare except: catches everything, including typos in your own code, which turns easy bugs into mysteries.

Several excepts, else and finally

Python
def safe_divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        print("Cannot divide by zero")
    except TypeError as err:
        print("Bad value:", err)
    else:
        print("Result:", result)
    finally:
        print("-- finished", a, "/", repr(b))

safe_divide(10, 4)
safe_divide(10, 0)
safe_divide(10, "2")

  • Python checks the except blocks from top to bottom and runs the first one that matches. To handle several types the same way, list them in a tuple: except (ValueError, TypeError):.
  • as err stores the exception object, so you can print its message.
  • else runs only if the try block raised nothing. It lets you keep the try block down to the one line that might fail.
  • finally runs no matter what: after success, after a handled error, even after an error nobody catches. Use it for clean-up such as closing a file.

Raising your own exceptions

When your code spots a problem it can't sensibly fix, such as a negative amount, use raise to report it. For errors that belong to your program, create your own exception type. You don't need to know classes yet: the two-line class below is all it takes.

Python
class InsufficientFundsError(Exception):
    pass

def withdraw(balance, amount):
    if amount <= 0:
        raise ValueError("amount must be positive")
    if amount > balance:
        raise InsufficientFundsError(f"balance is only {balance}")
    return balance - amount

for amount in [30, 500, -5]:
    try:
        print("New balance:", withdraw(100, amount))
    except (ValueError, InsufficientFundsError) as err:
        print(type(err).__name__ + ":", err)

Quick reference: Python Try...Except

4Python Try...Except: syntax

try:
    risky_code()
except SomeError as err:     # runs if SomeError happens
    handle(err)
except (ErrorA, ErrorB):     # several types at once
    handle_other()
else:                        # runs only if nothing was raised
    use_result()
finally:                     # always runs
    clean_up()

raise ValueError("message")  # signal a problem yourself

5Python Try...Except: run the example

Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.

Interactive example
def parse_quantity(text):
    qty = int(text)
    if qty < 0:
        raise ValueError("quantity cannot be negative")
    return qty

orders = ["3", "two", "5", "-1"]
total = 0

for text in orders:
    try:
        qty = parse_quantity(text)
    except ValueError as err:
        print(f"Skipped {text!r}: {err}")
    else:
        total += qty
        print(f"Added {qty}")

print("Total items:", total)
Expected outputAdded 3
Skipped 'two': invalid literal for int() with base 10: 'two'
Added 5
Skipped '-1': quantity cannot be negative
Total items: 8

7Python Try...Except: how the example works

Hover or tap a step to highlight its lines in the example above.

  1. Line 1-5parse_quantity() turns text into a whole number. int() raises ValueError by itself for text like "two", and the function raises its own ValueError for negative numbers.
  2. Line 7-8The orders arrive as strings, as if typed into a web form. total starts at 0.
  3. Line 10-12The call that might fail sits inside try, so a bad order can't crash the whole loop.
  4. Line 13-14except ValueError as err catches both kinds of problem. err holds the exception, and printing it shows its message. The loop then moves on to the next order.
  5. Line 15-17else runs only when the try block succeeded, so only valid quantities are added to the total.
  6. Line 19After the loop the total is 3 + 5 = 8. Two orders were rejected, but the program kept running to the end.

8Python Try...Except: common mistakes

Using a bare except that hides real bugs

✗ Wrong

def average(nums):
    try:
        return sum(nums) / len(numbers)
    except:
        return 0

print(average([4, 6]))
Prints 0 instead of 5.0, with no error: the NameError for the typo numbers was silently swallowed

✓ Right

def average(nums):
    try:
        return sum(nums) / len(nums)
    except ZeroDivisionError:
        return 0

print(average([4, 6]))

Catch only the exception you expect (here ZeroDivisionError for an empty list). Unexpected errors such as typos will then show up with a clear traceback.

Using a variable that the failed try never created

✗ Wrong

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Something went wrong")

print(result)
NameError: name 'result' is not defined

✓ Right

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Something went wrong")
    result = None

print(result)

When the line in try fails, the assignment never happens. Give the variable a fallback value inside except, or only use it in an else block.

Catching the wrong exception type

✗ Wrong

try:
    age = int("twelve")
except TypeError:
    print("Please type a number")
ValueError: invalid literal for int() with base 10: 'twelve' (the except block never ran)

✓ Right

try:
    age = int("twelve")
except ValueError:
    print("Please type a number")

int() with text that isn't a number raises ValueError, not TypeError. Read the last line of the traceback to learn the real exception type, then catch that one.

9Python Try...Except: exercises

Write your answer, then press Check. The checks run in your browser.

1. A safe number converter

Write code Easy

Change safe_int(text) so it returns int(text) when the text is a whole number, and returns None instead of crashing when it isn't. For example safe_int("12") is 12 and safe_int("hello") is None.

Your code
def safe_int(text):
    # return None if text is not a whole number
    return int(text)

print(safe_int("12"))

2. Predict the order

Predict the output Medium

Read the code and type exactly what it will print. Pay attention to which blocks run for each call. Then press Check to compare.

Read this code
def check(value):
    try:
        number = 100 / value
    except ZeroDivisionError:
        print("A")
    else:
        print("B", number)
    finally:
        print("C")

check(4)
check(0)

2 more exercises → 4 more examples

Finished this lesson?
Progress is saved in this browser — create a free account to keep it across devices.

Questions learners ask

Should I use a bare except or except Exception?

Neither, if you can avoid it. Catch the specific exception you expect, such as ValueError or KeyError, so unexpected bugs still show up. A bare except: is the worst choice because it also catches things like KeyboardInterrupt. If you really need a catch-all, use except Exception as err: and at least print or log err.

What is the difference between else and finally in try/except?

else runs only when the try block finished without an exception, so it is the place for code that depends on the try succeeding. finally runs every time: after success, after a handled exception and even when an exception is not caught. Use finally for clean-up such as closing files.

When should I raise an exception instead of returning None?

Raise an exception when the caller cannot sensibly continue, for example a negative price or a missing required setting. Returning None is easy to forget to check, and the program then fails later with a confusing TypeError far from the real cause. An exception stops at the exact spot and explains the problem.

Further reading

10Next lesson

Up nextPython TypeError: What It Means and How to Fix ItA TypeError means Python was asked to do something with a value whose type doesn't support it, such as adding a number …

Related:
Python TypeError: What It Means and How to Fix ItPython KeyError: What It Means and How to Fix ItPython IndexError: list index out of rangePython File Handling

← Python datetime Module · All Errors and Exceptions lessons · Practise in the IDE