Programming Fundamentals › Error Handling
Guard Clause
Returning early on invalid cases to avoid deep nesting.
Also known as: early return, guard clauses, bouncer pattern
A guard clause checks for a bad or special case at the top of a function and returns (or raises) right away, so the rest of the function can assume things are fine.
Compare nested conditions:
def ship(order):
if order is not None:
if order.is_paid:
if order.items:
return create_shipment(order)
else:
raise ValueError("empty order")
else:
raise ValueError("not paid")
else:
raise ValueError("no order")
with guards:
def ship(order):
if order is None:
raise ValueError("no order")
if not order.is_paid:
raise ValueError("not paid")
if not order.items:
raise ValueError("empty order")
return create_shipment(order) # the real work, no nesting
Both do the same thing. The second reads top to bottom: the checks first, then the point of the function at the normal indentation level.
Why it helps
- Less nesting, so fewer lines to hold in your head.
- Each failure case sits next to its error message.
- The “happy path” is easy to find: it’s what’s left at the bottom.
When not to use it
A function with many returns in complex logic can get hard to follow. If a function needs
five guards, check whether it’s doing too much or whether the inputs should be validated
earlier. Also be consistent about what a guard does: raise an error, or return a default
value. Guard clauses are the everyday form of failing fast.