๐ WAYPOINT LESSON
Defensive Programming
โญ beginnerโณ 10 min read๐ Lesson 29 of 169
Validate at the boundary, raise on broken invariants, and turn silent bugs into loud ones.
raise throws an exception deliberately โ when the data is wrong, fail loudly:
def set_price(price):
if price < 0:
raise ValueError(f"price cannot be negative, got {price}")
return price
A function that fails fast with a clear message is kinder than one that returns nonsense and lets the bug surface three layers away. Raising early converts a silent logic error into a loud, debuggable runtime error.
Defensive checks in practice
def average(values):
if not values: # None, [], empty โ all falsy
raise ValueError("average of empty data is undefined")
return sum(values) / len(values)
The check is one line; the debugging time it saves is hours. As a rule: validate at the boundary (where data enters your program), raise inside (when your own invariants break).