1.3.6Python Intermediate

Raising exceptions — raise, custom exception classes

1,936 words9 min readdifficulty · medium

WHY do we raise at all?

The core trade-off (this is the 80/20 idea):

  • Return a value when there's a meaningful result (including "not found" sometimes).
  • Raise an exception when continuing would be a bug or invalid state.

WHAT is raise?

raise ValueError("amount must be positive")   # instance created from class + message
raise ValueError                              # class — Python instantiates it with no args

HOW does it flow? (derive the mechanism from scratch)

When raise runs, Python does, step by step:

  1. Build the exception object (if you gave a class, call it).
  2. Attach a traceback recording where we are right now.
  3. Abandon the current line; look outward for an except that matches.
  4. Check enclosing try blocks in this function. None? Pop this frame.
  5. Repeat in the caller's frame... up and up.
  6. If nobody catches it, it reaches the top → program prints the traceback and exits.

Custom Exception Classes — WHY make your own?

class InsufficientFundsError(Exception):
    """Raised when a withdrawal exceeds the balance."""
    pass

Deriving a richer custom exception (carry data!)

Sometimes the handler needs facts, not just a name. Add an __init__:


Figure — Raising exceptions — raise, custom exception classes

raise with no arguments — re-raising

raise ... from ... — exception chaining


Common Mistakes (Steel-man + fix)


Active Recall

Recall What is the difference between

raise ValueError and raise ValueError("x")? The first passes the class; Python instantiates it with no message. The second passes an instance with the message stored in .args. Both work.

Recall Which class should custom exceptions inherit from, and why not

BaseException? Inherit from Exception. BaseException also covers SystemExit/KeyboardInterrupt, which shouldn't be swept up by ordinary error handling.

Recall What does a bare

raise inside an except do? Re-raises the current exception with its original traceback intact.

Recall What does

raise B from A accomplish? Sets B.__cause__ = A, chaining the exceptions so the traceback shows the original as the direct cause.


Recall Feynman: explain to a 12-year-old

Imagine you're a waiter taking an order. Normally you bring back food (a return value). But if the kitchen is on fire, you can't bring food — instead you run out yelling "FIRE!" (that's raise). Whoever hears you (an except) can decide what to do: call 911, or yell even louder so the manager upstairs hears (re-raise). A custom exception is like having different specific shouts: "FIRE!", "OUT OF PIZZA!", "WE'RE CLOSED!" — so listeners know exactly which problem to handle.


Connections

  • Try-Except-Finally — how raised exceptions get caught
  • Exception Hierarchy & BaseException — what you're inheriting from
  • Classes and __init__ — building the custom exception's constructor
  • Logging in Python — the log-and-re-raise pattern
  • assert statement — a lighter cousin that raises AssertionError

What statement throws an exception in Python?
raise (followed by an exception instance or class)
What base class should custom exceptions inherit from?
Exception
Why not inherit from BaseException?
It includes SystemExit/KeyboardInterrupt, which shouldn't be caught by normal handlers
What does a bare raise (no args) do inside except?
Re-raises the current exception, preserving its traceback
What does raise B from A do?
Chains exceptions: sets B.__cause__ = A so the cause is shown
Where is the message of an exception stored?
In its .args tuple, set via super().__init__(msg)
Difference between raise ValueError and raise ValueError("x")?
First is the class (auto-instantiated, no msg); second is an instance with a message
Why raise instead of returning an error code?
Forces the caller to handle the problem; prevents silent corrupt-state continuation
What happens if no except ever catches a raised exception?
It propagates to the top, prints a traceback, and the program exits
What method must a data-carrying custom exception call, and why?
super().__init__(message) — to populate .args so str(e) prints correctly

Concept Map

for real answers

for invalid state

interrupts

propagates

inherits from

ultimately from

walks up

matched by

if uncaught

can create

subclass of

enables

Return value

Meaningful result

raise statement

Bug or invalid state

Normal execution

Exception object

Exception class

BaseException

Call stack

except block

Traceback and exit

Custom exception class

Specific except handling

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, normal function toh ek value return karta hai — jaise jawab dena. Lekin kabhi kabhi sahi jawab dena hi possible nahi hota. Jaise int("hello") — isme number hai hi nahi return karne ko. Aise time pe Python ek galat jhootha jawab dene ke bajaye exception raise kar deta hai, matlab zor se cheekh ke bolta hai "yahan problem hai!". raise keyword tumhare apne code ko bhi aise cheekhne ki power deta hai jab koi invalid cheez detect ho.

raise ValueError("amount must be positive") likho, toh current line chhod ke Python upar ki taraf — caller ke paas, uske caller ke paas — ek matching except dhoondhta hai. Mil gaya toh handle, nahi mila toh program crash ho jaata hai with traceback. Yaad rakho: sirf exception object banana (make) kaafi nahi — return ValueError(...) galti hai. Usko raise karna padta hai, tabhi woh actually phekta hai.

Custom exception banane ka faayda yeh hai ki error ka ek naam ho jaata hai, jiska matlab clear ho. class InsufficientFundsError(Exception): pass — bas itna. Hamesha Exception se inherit karo, BaseException se kabhi nahi (warna Ctrl-C jaise signals bhi fas jaate hain). Agar exception ke saath data bhejna ho (jaise balance, shortfall), toh __init__ likho aur andar super().__init__(message) zaroor call karo — warna print(e) khaali aayega.

Do aur cheezein: andar except mein akela raise likho toh wahi exception dobara aage bhej deta hai (log karke). Aur raise NayaError(...) from purana_error se dono errors chain ho jaate hain — traceback mein asli cause dikhta rehta hai. Bas itna 80/20 yaad rakho aur tum exceptions ke master ho.

Go deeper — visual, from zero

Test yourself — Python Intermediate

Connections