Python Try Except

Python try except blocks let you handle errors (called exceptions) instead of letting them crash your program. Code that might fail goes in the try block, and the except block says what to do if a particular error happens.

A Basic try except

try:
    result = 10 / 0
except ZeroDivisionError:
    result = None
    print("You cannot divide by zero")

print("Result:", result)
You cannot divide by zero
Result: None

Uncaught Exceptions

Without try except, the program stops and Python reports the error type and message. Run this example to see what an unhandled error looks like.

numbers = [1, 2, 3]
print("Before the error")
print(numbers[5])
print("This line never runs")
Before the error
IndexError: list index out of range

Catching Multiple Exceptions

Use several except blocks for different errors, or group them in a tuple. as e gives you the exception object with its message.

def safe_divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        return "cannot divide by zero"
    except (TypeError, ValueError) as e:
        return f"bad input: {e}"

print(safe_divide(9, 3))
print(safe_divide(9, 0))
print(safe_divide(9, "x"))
3.0
cannot divide by zero
bad input: unsupported operand type(s) for /: 'int' and 'str'

else and finally

else runs only if no exception happened. finally always runs, error or not, which makes it the place for clean-up work such as closing files or connections.

for text in ["25", "abc"]:
    try:
        n = int(text)
    except ValueError:
        print(text, "-> not a number")
    else:
        print(text, "-> doubled is", n * 2)
    finally:
        print("checked", text)
25 -> doubled is 50
checked 25
abc -> not a number
checked abc

Raise an Exception

Use raise to signal an error yourself, for example when a function receives a value it cannot accept.

def set_age(age):
    if age < 0:
        raise ValueError("age cannot be negative")
    return age

try:
    set_age(-5)
except ValueError as e:
    print("Error:", e)
Error: age cannot be negative

Custom Exceptions

Create your own exception by subclassing Exception. Specific exception types make it easy for callers to catch exactly the problem they care about.

class OutOfStockError(Exception):
    pass

def buy(product, stock):
    if stock == 0:
        raise OutOfStockError(f"{product} is out of stock")
    return f"Bought {product}"

try:
    print(buy("Tea", 5))
    print(buy("Honey", 0))
except OutOfStockError as e:
    print(e)
Bought Tea
Honey is out of stock

Common Built-in Exceptions

  • ValueError: right type but invalid value, like int("abc")
  • TypeError: wrong type, like 1 + "2"
  • KeyError: missing dictionary key
  • IndexError: list index out of range
  • ZeroDivisionError: division by zero
  • FileNotFoundError: the file does not exist
  • AttributeError and NameError: unknown attribute or variable name

Frequently asked questions

Should I use a bare except in Python?

Avoid it. A bare except: also catches things like KeyboardInterrupt and hides bugs. Catch specific exceptions, or at least except Exception as e.

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

else runs only when the try block succeeded without an exception. finally runs every time, whether an exception happened or not.

How do I print the error message of an exception?

Catch it with a name, as in except ValueError as e:, then print(e) or use str(e) to get the message.