Python Error Handling (try/except)
Learn Python error handling with try and except: catch exceptions, handle specific error types, validate user input, and use else and finally. Write robust programs with runnable code, a worked example and a quiz.
Key takeaways
- An exception is a runtime error that stops a program unless you handle it
- Code that might fail goes in a try block; the response goes in an except block
- Catch specific exception types like ValueError or ZeroDivisionError, not just any error
- try/except is ideal for validating user input without crashing
- else runs when no error happened, and finally always runs for cleanup
When good programs go wrong
Even perfectly written code can run into trouble. A user types "ten" when you asked for a number. A file you tried to open isn't there. You divide by a value that turns out to be zero. When something like this happens, Python raises an exception — a special signal that something went wrong. If you do nothing, that exception crashes your program with a wall of red text. Error handling is how you stay in control: you catch the problem, respond sensibly, and keep running.
If you're comfortable with conditionals and functions, you're ready to make your programs robust.
What an exception looks like
Let's see a program crash on purpose:
number = int("hello")
print("This line never runs")
int("hello") can't turn the word "hello" into a number, so Python raises a ValueError and stops immediately. You'll see a traceback ending with:
ValueError: invalid literal for int() with base 10: 'hello'
The crucial detail: the second line never runs. An unhandled exception halts everything that follows.
The try and except blocks
To handle an exception, wrap the risky code in a try block and describe your response in an except block:
try:
number = int("hello")
print("Converted successfully")
except ValueError:
print("That wasn't a valid number.")
print("The program keeps going.")
Reading it line by line:
- The
try:block holds the code that might fail. int("hello")raises aValueError, so Python skips the rest of the try block (the success message never prints) and jumps to the matchingexcept.except ValueError:catches that specific error and runs its body, printing a friendly message.- Because the exception was handled, the program doesn't crash — the final line still runs, printing
The program keeps going.
That's the whole idea: try the risky thing, and if it fails, respond instead of crashing.
Catch specific exceptions
Different problems raise different exception types. Two of the most common:
ValueError— a value is the wrong kind, likeint("hello").ZeroDivisionError— you divided by zero.
try:
a = int("8")
b = int("0")
print(a / b)
except ValueError:
print("Please enter whole numbers only.")
except ZeroDivisionError:
print("You can't divide by zero!")
- Here the conversions succeed, but
a / bis8 / 0, which raises aZeroDivisionError. - Python checks each
exceptin order and runs the one that matches, printingYou can't divide by zero!.
You can list several except blocks, each handling a different type. This is far better than catching everything, because a specific catch only handles the problems you actually expect — and lets genuinely unexpected bugs surface so you can fix them.
A practical use: validating input
The most common real-world use of try/except is making user input safe. Whatever a person types arrives as text, and converting it to a number can fail. If you've used input and output, this makes those programs unbreakable.
age_text = input("How old are you? ")
try:
age = int(age_text)
print("Next year you'll be", age + 1)
except ValueError:
print("That doesn't look like a number.")
input(...)always returns a string, soage_textmight be"15"or"fifteen".- If it's
"15",int(age_text)succeeds and the program prints the next age. - If it's
"fifteen", the conversion raises aValueError, theexceptruns, and the program politely explains instead of crashing.
Capturing the error message
You can grab the exception itself with as to learn more about what went wrong:
try:
value = int("3.5")
except ValueError as error:
print("Something went wrong:", error)
except ValueError as error:stores the exception object inerror.- Printing it shows Python's own description of the problem, which is useful while debugging.
else and finally
Two optional extras complete the picture.
An else block runs only if the try finished without an error:
try:
number = int("42")
except ValueError:
print("Not a number.")
else:
print("Success! The number doubled is", number * 2)
Because int("42") succeeds, the except is skipped and the else runs, printing Success! The number doubled is 84. Putting the "everything went fine" code in else keeps the try block focused only on the line that might fail.
A finally block runs no matter what — whether or not an exception happened. It's the place for cleanup, like closing a file:
try:
print(10 / 0)
except ZeroDivisionError:
print("Caught a division error.")
finally:
print("This always runs.")
This prints Caught a division error. and then, unconditionally, This always runs.. Even if no except matched, finally would still execute.
Worked example: a safe calculator
Let's build a small division calculator that survives bad input and division by zero.
def safe_divide(top_text, bottom_text):
try:
top = int(top_text)
bottom = int(bottom_text)
result = top / bottom
except ValueError:
return "Both inputs must be whole numbers."
except ZeroDivisionError:
return "Cannot divide by zero."
else:
return f"{top} / {bottom} = {result}"
print(safe_divide("10", "2")) # 10 / 2 = 5.0
print(safe_divide("10", "0")) # Cannot divide by zero.
print(safe_divide("ten", "2")) # Both inputs must be whole numbers.
How it works:
- The
tryblock attempts both conversions and the division. Any of them might fail. - If a conversion fails,
ValueErroris caught and a clear message is returned. If the bottom is zero,ZeroDivisionErroris caught instead. - If nothing failed, the
elseblock builds and returns the result. By returning from inside the function, each path gives back exactly one clean answer.
Run all three calls and notice the program never crashes — every kind of bad input produces a helpful message instead.
Try it yourself
Turn the calculator into an interactive loop:
- Repeatedly ask the user for two numbers with
input(). - Use
try/exceptto catch aValueError(non-numbers) and aZeroDivisionError(dividing by zero), printing a friendly message for each. - Add an
elseblock that prints the result only when the division succeeds. - Let the user type
quitto stop. (Hint: pair this with a while loop that keeps going until they quit.)
Test it with "5" and "0", then "cat" and "3", then "20" and "4". A well-handled program should sail through all three without ever crashing.
Quick quiz
Test yourself and earn XP
What is an exception in Python?
An exception is an error raised while the program runs, such as dividing by zero. If not handled, it stops the program.
Which block holds the code that might cause an error?
You put the risky code in the try block. If it raises an exception, Python jumps to the matching except block.
What error does int("hello") raise?
int() cannot turn the text "hello" into a number, so it raises a ValueError.
Why is it better to catch a specific exception than to catch everything?
Catching a specific type means unexpected errors still surface, instead of being silently swallowed and hiding real bugs.
When does a finally block run?
finally always runs at the end, making it the right place for cleanup such as closing a file.
FAQ
In everyday speech people use them interchangeably, and in Python they are closely linked. A syntax error means your code is written incorrectly and won't even start to run — you must fix the typo. An exception happens while a correctly written program is running, when something goes wrong at that moment, such as dividing by zero or trying to convert bad input. try/except is for exceptions, the runtime kind. It cannot rescue a syntax error, because that code never runs at all.
Almost never in normal code. A bare except catches every possible exception, including ones you didn't anticipate and even some that signal the program should stop, like the user pressing Ctrl+C. That can hide real bugs and make problems much harder to debug. The good habit is to catch the specific exception you expect, such as except ValueError, so that genuinely unexpected errors still show up loudly and get fixed.
Keep exploring
More in Coding