Lesson 17 of 21 · 54 min · UG / professional
Exceptions: try, except, raise
Syntax errors never run. Runtime errors can be caught. raise is how you refuse garbage with a name. User-defined errors are classes on a laptop; here a status string starts the same policy.
Broken form input
Check values before you calculate.
You will be able to
- ✓ Separate syntax errors (never run) from runtime errors (can be caught)
- ✓ Use guards and status strings here; try/except/raise on a laptop
- ✓ Refuse garbage with a named failure — do not store “n/a” as a phone number
A form that sends “twelve” is expected
People type twelve, 12, and 12.0. A night job receives an empty file. Syntax errors (a missing colon) never start the program. Runtime errors happen while it runs: int("twelve") on a laptop raises ValueError. try/except catches the error you expect. raise is how you refuse garbage with a name so callers cannot ignore it. User-defined errors are classes on a laptop; here a status string — OK or Reject — starts the same policy.
Guard clauses are the sandbox version: if len(pin) != 6: return "Reject". On a laptop you might raise ValueError("PIN must be 6 digits"). Either way, name the policy. A bare except that swallows everything will hide a bug in your own arithmetic — do not do that in production.
Laptop: try, except, raise
def parse_seats(text):
try:
n = int(text)
except ValueError:
raise ValueError("seats must be whole digits") from None
if n < 0:
raise ValueError("seats cannot be negative")
return n
Fail at the edge, keep the core boring
late_fee(days) can assume days is already an int >= 0. parse_days(text) is where “twelve” dies. Split those jobs so tests for the fee table never need a try. Exceptions are policy for the edge and for truly unexpected disk failures — not a second if/else language for every branch.
raise in a library is a contract: “I will not return a fake 0 for a bad GSTIN.” Returning 0 looks like a free bill. Reject is louder.
Words that matter
- Guard
- An early check that refuses bad input.
- Exception
- A named failure the machine (or you) raises — try/except on a laptop.
- raise
- Laptop: throw a named error so callers must handle it.
- ValueError
- “This value cannot be used” — usual choice for bad form text.
Common mistakes
Avoid: except: pass around the whole program.
Do this: Catch the error you expect, name it, and let the rest surface.
Run it step by step
Each box is a real program. Press Run, change a number, Run again — the output must follow your code.
1. Step 1 — length is a policy
PIN must be 6 characters in this toy rule.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
2. Step 2 — refuse a short code
Callers get a status they can show. Nothing is stored.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
On a full Python install — try / except / raise
Catch the conversion you expect. raise a named error for policy. Never except: pass around the whole payroll.
stdlib — no pip
Named failure at the edge.
Real library code (not run in this browser sandbox)
def parse_pin(text):
if len(text) != 6:
raise ValueError("PIN must be 6 characters")
return text
try:
print(parse_pin("411"))
except ValueError as err:
print("Reject", err)
Example program — Seats cannot be negative
A human message, not a crash dump. Core maths never sees -3.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
Your turn — Reject 12
code = "12". Print Reject when len is not 6.
Edit the example, press Run, then Build if you want a compile check.
build
Press Build to compile.
Self-assessment
Check your understanding before you mark the lesson complete.
Progress is stored in a browser cookie on this device.