livepython.net
CHAPTER 17Handling Errors (Exceptions)
17.4  RAISE

Python raise: Raise Your Own Exceptions

What Does raise Do in Python?

The raise statement makes an exception happen on purpose. You use it when a value is wrong for your program, even though Python itself sees no problem with it.

PYTHONedit me
age = -5
if age < 0:
    raise ValueError("Age can't be negative")
print("Age saved")
OUTPUT
ValueError: Age can't be negative

To Python, -5 is a perfectly good number. But you know that nobody is minus five years old. raise stops the program right there, with your own message, before the bad value can cause trouble later.

Think of it like a referee's whistle. The players may not notice the foul, but the referee does, blows the whistle, and play stops.

How to write it

raise, then the error type, then your message in brackets:

raise ValueError("Marks must be 0 to 100")

The rules

  • A raised error behaves exactly like Python's own: the program stops, unless an except catches it.
  • The message is a string. Say what's wrong, and what's allowed.
  • Pick the error type that fits the problem:
ProblemType to raiseExample message
the right kind of value, but a bad oneValueError"Marks must be 0 to 100"
the wrong kind of valueTypeError"Price must be a number"

ValueError is the one you'll raise most: a negative age, marks over 100, an empty name.

Good messages

PYTHONedit me
marks = 150
if marks < 0 or marks > 100:
    raise ValueError(f"Marks must be 0 to 100, not {marks}")
OUTPUT
ValueError: Marks must be 0 to 100, not 150

An f-string (chapter 5) puts the bad value into the message, so whoever reads it sees exactly what went wrong. Compare that to a message like "Error", which tells you nothing.

raise ErrorType("message") stops the program on purpose when a value makes no sense.

your turnPredict the output

What will this print?

marks = 150 if marks > 100: raise ValueError("too high") print("ok")
Your turn! What will this code show on the screen?
your turnSpot the bug

Which line breaks?

One line stops this program. Tap it.

Raise a ValueError in Your Own Function

raise is most useful inside your own functions (chapter 15). When a function gets a value it can't work with, it raises an error instead of returning a wrong answer.

PYTHONedit me
def half_price(price):
    if price < 0:
        raise ValueError(f"Price can't be negative: {price}")
    return price / 2

print(half_price(80))
print(half_price(-10))
OUTPUT
40.0
ValueError: Price can't be negative: -10

The first call works. The second one stops at the source of the problem, with a message that says exactly what was wrong.

Think of it like a cashier who spots a fake banknote. They don't quietly give you the wrong change. They stop and say clearly what's wrong.

Avoid: print and carry on

A common beginner idea is to print() the problem inside the function:

PYTHONedit me
def half_price(price):
    if price < 0:
        print("Price can't be negative")
    else:
        return price / 2

print(half_price(-10) + 5)
OUTPUT
Price can't be negative
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

The function printed a message, then returned nothing, which is None (chapter 15). The program carried on, tried None + 5, and crashed somewhere else, with a confusing TypeError. The real problem is far away from where the error shows up.

Good: raise

With raise, the problem stops where it starts, with a clear message. And the code that called the function can decide what to do about it: show a friendly message, ask again, or stop. You'll do that in the next lesson.

The rules

  • Check the parameters at the start of the function.
  • If one is bad, raise with a clear message. Don't print() and carry on.
  • After a raise, the rest of the function doesn't run, just like after a return.

Common beginner doubt: "Isn't crashing worse than printing?" A crash with a clear message is much better than a program that keeps going with a wrong value. And it won't stay a crash: the next lesson shows how the caller catches it.

A function that gets a bad value should raise an error, not print and return None.

your turnFill the gap

Stop the bad value in the function

def check_age(age): if age < 0: ? ValueError("Age can't be negative") return age try: check_age(-3) except ValueError as e: print(e)

It should print: Age can't be negative

Which piece makes this code work?
your turnPick the right idea

What happens to the lines after a raise inside a function?

Think about it, then pick one.

Catch the Errors You Raise

An error you raise is caught exactly like one of Python's own: with try and except. So a function can raise, and the code that calls it decides what to tell the user.

PYTHONedit me
def check_marks(marks):
    if marks < 0 or marks > 100:
        raise ValueError("Marks must be 0 to 100")
    return marks

try:
    marks = check_marks(int(input()))
except ValueError as e:
    print("Problem:", e)
else:
    print("Saved:", marks)
OUTPUT
Problem: Marks must be 0 to 100

Now type 85: Saved: 85. And type abc: int() raises its own ValueError, and the same except catches it too.

Think of it like a smoke detector and a fire crew. The detector (the function) only raises the alarm. The crew (the caller) decides what to do about it.

Two jobs, two places

The functionThe caller
checks the valuecalls the function inside try
raises a clear error if it's badcatches it with except
returns the result if it's gooduses the result, often in else

This split keeps each part simple. The function works the same in every program. Each program can react in its own way: one prints a message, another asks again.

Errors travel up

If the function doesn't catch its error, the error leaves the function and travels up to the line that called it. That's why the try goes around the call, not inside the function.

try:
    marks = check_marks(150)    # the error comes out here
except ValueError as e:
    print("Problem:", e)

Common beginner doubt: "Can I make my own error types, like MarksError?" Python allows it, but it needs classes, from chapter 20. The built-in ValueError and TypeError, with a good message, cover almost everything you'll need.

Raise in the function, catch at the call: try around the call, except to explain.

your turnType the output

Type what this prints

def check_age(age): if age < 0: raise ValueError("negative") return age try: print(check_age(int(input()))) except ValueError as e: print("Error:", e)

The user types: -4

Read the code line by line, then type the output exactly.
your turnPredict the output

What will this print?

name = " sunny " print(name.strip().title())
Your turn! What will this code show on the screen?

Practice: raise

Solve these to lock in what you learned in this topic. Each one runs in your browser.

  1. 156.Python Program to Check an Age with raiseEasySolve
  2. 157.Python Program to Withdraw Money with raiseMediumSolve