Start.dev
Back to blog

Python try/except: handle errors without crashing

Learn Python try/except with real examples: catch specific errors, use else and finally, raise your own errors, and avoid the habits that hide bugs.

Ariel Weinberger
Ariel Weinberger ยท 5 min read

What do you do when a line of Python might fail, like converting what a user typed into a number?

Short answer: put the risky line inside a try block and say what to do instead in an except block. If the error happens, Python runs your except code rather than crashing the program.

try:
    age = int(input("Your age: "))
except ValueError:
    print("Please enter a whole number.")

By the end of this post you will be able to catch specific errors, handle different errors differently, use else and finally, raise your own errors, and avoid the habits that make bugs harder to find.

What happens without try/except

When Python hits an error it can't handle, it stops and prints a traceback:

age = int("twenty")
Traceback (most recent call last):
  File "main.py", line 1, in <module>
    age = int("twenty")
ValueError: invalid literal for int() with base 10: 'twenty'

Read the last line first. It tells you the type of error, ValueError, and a message saying what went wrong. The lines above it show where it happened. Reading A Traceback (opens in a new tab) walks through reading one.

That error type is what you name in except.

Your first try/except

text = "twenty"
 
try:
    age = int(text)
    print(f"Next year you will be {age + 1}")
except ValueError:
    print(f"'{text}' isn't a number")
'twenty' isn't a number

Here is what Python does:

  1. It runs the lines in try one by one.
  2. int(text) raises a ValueError, so Python stops the try block right there. The print inside try never runs.
  3. It looks for an except that matches ValueError, finds one, and runs it.
  4. The program carries on after the whole block, instead of crashing.

If text were "20", the try block would finish normally and the except block would be skipped. See Try And Except (opens in a new tab).

Errors you will meet most often

ErrorWhen it happensExample
ValueErrorRight type, wrong valueint("abc")
TypeErrorWrong type for the operation"5" + 3
ZeroDivisionErrorDividing by zero10 / 0
KeyErrorA dictionary key that isn't thereprices["tea"]
IndexErrorA list position that doesn't exist[1, 2][5]
FileNotFoundErrorOpening a file that doesn't existopen("missing.txt")

Handling different errors differently

One try can have several except blocks. Python uses the first one that matches:

def average(total, count):
    try:
        return total / count
    except ZeroDivisionError:
        print("No items, so no average.")
        return None
    except TypeError:
        print("Total and count need to be numbers.")
        return None
 
average(50, 0)    # No items, so no average.
average("50", 5)  # Total and count need to be numbers.

If two errors need the same handling, group them in a tuple:

except (ValueError, TypeError):
    print("That input won't work.")

See Handling Different Errors (opens in a new tab).

Getting the error message with as

as gives you the error itself, so you can show or log its message:

prices = {"coffee": 3.5, "cake": 4.0}
 
try:
    print(prices["tea"])
except KeyError as error:
    print(f"Not on the menu: {error}")
Not on the menu: 'tea'

For a missing dictionary key specifically, prices.get("tea") returns None instead of raising. Use whichever reads better. try/except is the general tool, and .get() is a shortcut for this one case.

else and finally

Two more optional blocks:

  • else runs only if the try block finished without an error.
  • finally runs every time, error or not. It is for cleanup.
text = "42"
 
try:
    number = int(text)
except ValueError:
    print("Not a number.")
else:
    print(f"Doubled: {number * 2}")
finally:
    print("Done checking.")
Doubled: 84
Done checking.

Why use else instead of putting that line inside try? It keeps the try block small, so you only catch errors from the line you expected to fail, not from the code after it. See Else And Finally (opens in a new tab).

Asking again until the input is valid

A common real use: keep asking until the user types something usable. Combine try with a while loop:

while True:
    try:
        quantity = int(input("How many tickets? "))
        break
    except ValueError:
        print("Please type a whole number, like 2.")
 
print(f"Booking {quantity} tickets")

If int() succeeds, break ends the loop. If it fails, the except prints a hint and the loop asks again. Python input(): get user input and validate it covers more input patterns.

Raising your own errors

Sometimes the input is technically valid Python but wrong for your program, like a negative quantity. Use raise to signal that:

def set_quantity(n):
    if n < 1:
        raise ValueError("Quantity must be at least 1")
    return n
 
try:
    set_quantity(0)
except ValueError as error:
    print(error)  # Quantity must be at least 1

The function says what is wrong, and the code that called it decides what to do. See Raising Errors (opens in a new tab).

Common mistakes

  • A bare except:. It catches everything, including KeyboardInterrupt when you press Ctrl+C to stop a program. Always name the error you expect.
  • except Exception: pass. This hides every error silently. The program carries on with bad data, and you lose the message that would tell you why. If you catch something, do something with it.
  • Putting too much inside try. If ten lines are in the try block, you can't tell which one failed. Wrap only the line that can raise, and move the rest to else or after the block.
  • Using try/except to hide a bug. If a TypeError keeps appearing, the fix is usually in the code that passed the wrong type, not a wider except.
  • Catching the wrong type. except ValueError won't catch a ZeroDivisionError. Read the traceback's last line and catch that type.

Quick recap

  • Put the risky line in try, and the fallback in except.
  • Name the specific error you expect, like ValueError or KeyError.
  • Use several except blocks, or a tuple, to handle different errors.
  • else runs when nothing failed. finally always runs.
  • raise signals your own errors, with a clear message.

Frequently asked questions

What does try/except do in Python?

It lets you run code that might fail and decide what happens if it does. Code in try runs first. If it raises a matching error, Python runs the except block instead of stopping the program.

Can you have multiple except blocks?

Yes. Python checks them in order and runs the first one that matches the error. You can also catch several types in one block with a tuple, like except (ValueError, TypeError):.

What is the difference between else and finally?

else runs only when the try block finished without an error. finally runs every time, whether an error happened or not, which makes it the place for cleanup.

Should I use a bare except?

No. A bare except: catches every error, including ones you never meant to handle, like pressing Ctrl+C. Name the error you expect so other problems still show up.

How do I print the error message?

Use as to name the error, then print it: except ValueError as error: print(error).

Practice

The matching exercises are in the course. Start with How Exceptions Work (opens in a new tab), catch your first error in Try And Except (opens in a new tab), then put it together in Unbreakable Calculator (opens in a new tab). Each exercise runs Python in your browser, so there is nothing to install.

Keep going

Intermediate Python (opens in a new tab) covers errors alongside input, files, APIs and classes, the parts of Python where things can actually go wrong. If loops and functions still feel new, start with Python for Beginners (opens in a new tab).

Level up your coding skills

Jump into interactive courses and start building real-world projects.

Start learning

Related posts

Python input() always returns a string. Learn to convert it, catch bad answers, ask again in a loop, and reuse that in a function.
Ariel Weinberger
Ariel Weinberger ยท 6 min read
Python lists, tuples and dictionaries compared with simple examples: how each one works, how they differ, and a quick rule for picking the right one.
Ariel Weinberger
Ariel Weinberger ยท 4 min read
A day-by-day Python roadmap for your first 30 days: what to learn, what to build each week, and the mistakes that stall most beginners.
Ariel Weinberger
Ariel Weinberger ยท 7 min read