When an input is illegal, raise. When you can recover, except. Do not catch everything and ignore it.
Goal
Raise ValueError for bad units, catch it at the edge, and define a small custom exception.
Raise
def line_total(units, price):
if units < 0 or price < 0:
raise ValueError("units and price must be >= 0")
return round(units * price * 1.16, 2)
print(line_total(2, 10))Catch at the edge
def line_total(units, price):
if units < 0 or price < 0:
raise ValueError("units and price must be >= 0")
return round(units * price * 1.16, 2)
def main():
try:
print(line_total(-1, 10))
except ValueError as err:
print("could not price line:", err)
if __name__ == "__main__":
main()Custom exception
class KioskError(Exception):
"""A kiosk inventory problem."""
def require_city(city):
label = str(city or "").strip()
if not label:
raise KioskError("city is required")
return label.title()
print(require_city("nakuru"))
try:
require_city(" ")
except KioskError as err:
print("caught", type(err).__name__, err)Pitfall
except Exception: pass hides bugs. Catch the type you expect, or let it fail with a traceback.