Errors, Validation, and Debugging
Catch Only What You Can Handle
Avoid a catch-all
This code is too broad:
text = "3"
recipe_cost = 24
try:
servings = int(text)
total = recipe_cost / servngs
except:
print("Please enter a number.")
The misspelled name servngs causes a except: catches it anyway and prints misleading advice. The user can enter numbers forever, but that cannot repair the programmer’s typo.
The same problem appears with:
except Exception:
print("Something went wrong.")
That is more explicit syntax, but it still groups many unrelated failures together.
Match the handler to the recovery
Protect the expected conversion only:
try:
servings = int(text)
except ValueError:
print("Please enter a whole number.")
Now invalid text receives actionable guidance. A later NameError, ZeroDivisionError, or other unexpected exception remains visible with its
That visibility is valuable. It tells the programmer what actually needs repair.
Keep try blocks small
Compare:
try:
count = int(text)
subtotal = count * price
print(make_label(subtotal))
except ValueError:
print("Enter a whole number.")
with:
try:
count = int(text)
except ValueError:
print("Enter a whole number.")
The first block contains three operations. If another operation raises ValueError, the handler may blame the input incorrectly. The second block makes the intended relationship clear.
Three questions before catching
Ask:
Which exact operation can fail?
Which exact exception does it raise?
What meaningful recovery can the program perform?
If you cannot answer all three, let the exception remain visible while you investigate.
An exception handler is not a way to declare a program reliable. Reliability comes from understanding expected failures, validating assumptions, and preserving useful evidence for unexpected ones.
What is the main danger of a bare except: in beginner input code?
Which try block is easiest to reason about when handling invalid integer text?