Raising Exceptions in Python

raise lets you stop your program and report a problem clearly.

You use it when something is wrong with the data, the input, or the current state of the program. This helps you catch bugs early and makes your code easier to understand.

Quick example

age = -1

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

Use raise when you want your code to stop and report a problem clearly.

What raising an exception means

An exception is an error signal in Python.

When you write raise, you tell Python to create that error right now. If the exception is not caught, the program stops and shows an error message.

Basic idea:

  • An exception signals that something went wrong.
  • raise creates that exception.
  • It stops normal execution unless try and except catch it.

Example:

score = 150

if score > 100:
    raise ValueError("score must be between 0 and 100")

Here, Python raises a ValueError because the value is outside the allowed range.

If you are new to this topic, see what an exception is in Python for the basic definition.

When to use raise

Use raise when your code finds a real problem.

Common cases:

  • Validate function inputs
  • Stop when required data is missing
  • Reject values outside an allowed range
  • Catch bugs early instead of letting them cause confusing errors later

Example:

name = ""

if not name:
    raise ValueError("name is required")

This is better than letting the program continue with bad data.

Basic raise syntax

The most common pattern is:

raise ExceptionType("message")

Example:

raise ValueError("price cannot be negative")

This has two parts:

  • ValueError is the exception type
  • "price cannot be negative" is the message

Try to choose an exception type that matches the problem. A clear message makes debugging much easier.

Common built-in exceptions to raise

Python has many built-in exception types. Here are some of the most common ones you will raise yourself.

ValueError

Use ValueError when the type is correct, but the value is wrong.

age = -5

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

TypeError

Use TypeError when the value has the wrong type.

name = 123

if not isinstance(name, str):
    raise TypeError("name must be a string")

KeyError

Use KeyError when a required dictionary key is missing.

user = {"name": "Ava"}

if "email" not in user:
    raise KeyError("email")

IndexError

Use IndexError for a bad list or tuple index.

numbers = [10, 20, 30]
index = 5

if index >= len(numbers):
    raise IndexError("list index out of range")

RuntimeError

Use RuntimeError for a general runtime problem when no better built-in type fits.

connected = False

if not connected:
    raise RuntimeError("database is not connected")

If you want a broader introduction first, read Python errors and exceptions explained. For specific error types, see ValueError in Python: causes and fixes and TypeError in Python: causes and fixes.

Raising exceptions in functions

It is usually best to check inputs near the start of a function.

This is called failing early. It makes the function behavior clearer and prevents bad data from spreading through your code.

Example:

def divide(total, count):
    if not isinstance(total, (int, float)):
        raise TypeError("total must be a number")

    if not isinstance(count, int):
        raise TypeError("count must be an integer")

    if count == 0:
        raise ValueError("count cannot be zero")

    return total / count


print(divide(10, 2))

Output:

5.0

If you call divide(10, 0), the function raises a clear error right away.

How raise works with try and except

A raised exception can be caught with except.

If it is not caught, the program stops with an error message. You can also raise an exception inside a try block, or catch one exception and raise a different one.

Example:

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

try:
    set_age(-2)
except ValueError as error:
    print("Caught an error:", error)

Output:

Caught an error: age cannot be negative

You can also convert one error into another:

data = {"count": "abc"}

try:
    count = int(data["count"])
except ValueError:
    raise TypeError("count must contain a valid integer")

This can be useful, but do it carefully so you do not hide the real cause.

For more on this pattern, see using try, except, else, and finally in Python.

Re-raising an exception

Sometimes you want to do something when an error happens, such as logging or printing a message, and then let the same exception continue upward.

Use plain raise inside an except block:

try:
    number = int("hello")
except ValueError:
    print("Could not convert the text to an integer")
    raise

This keeps the original exception information.

That is better than creating a completely new exception if you still want the original traceback.

Creating custom exceptions

You can create your own exception class for special cases.

This is useful in larger programs where built-in exceptions are not specific enough.

A custom exception usually inherits from Exception:

class InvalidUsernameError(Exception):
    pass


username = "ab"

if len(username) < 3:
    raise InvalidUsernameError("username must be at least 3 characters long")

Custom exceptions make your code easier to read because the error name explains the problem.

How to write useful exception messages

A good exception message should help someone fix the problem quickly.

Tips:

  • Say what was wrong
  • Include the bad value when helpful
  • Keep the message short
  • Avoid vague messages like "something went wrong"

Good example:

quantity = -4

if quantity < 0:
    raise ValueError(f"quantity cannot be negative: {quantity}")

Less helpful example:

raise ValueError("invalid input")

The first message tells you exactly what failed.

Common mistakes

Here are common problems beginners run into when using raise:

  • Raising the wrong exception type for the problem
  • Using raise for normal program flow instead of real errors
  • Forgetting to include a helpful message
  • Raising generic Exception when ValueError or TypeError would be clearer
  • Catching an exception and hiding the real cause

For example, this is usually too general:

age = -1

if age < 0:
    raise Exception("bad age")

This is clearer:

age = -1

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

If you are debugging, these commands can help:

python your_script.py
print(type(value), value)
help(ValueError)
help(TypeError)

FAQ

What is the difference between raise and except?

raise creates an exception. except catches an exception.

Should I use ValueError or TypeError?

Use TypeError for the wrong type. Use ValueError for the right type but a bad value.

Can I raise my own exception class?

Yes. Create a class that inherits from Exception, then raise it.

Does raise always stop the program?

It stops normal execution unless the exception is caught by try-except.

Can I raise an exception without a message?

Yes, but a short message is usually better for debugging.

See also