Skip to content
Educora
Intermediate15 min11 / 42

Handling errors: try and except

Stop your program from crashing: recognise exceptions, catch them with try/except/else/finally and raise your own.

Check yourself
In this lesson you will learn
  • Recognise the most common exceptions
  • Catch an error with try and except and keep the program running
  • Use else, finally and raise

You have written a calculator. The user types “twelve” instead of a number, or divides by zero — and the program stops with a red error message. Nobody likes a program like that! A good program is ready for mistakes: it recognises the problem, explains it clearly to the user and carries on.

What are exceptions?

There are two kinds of errors. Syntax errors (SyntaxError) are mistakes in how the code is written, and the program does not even start. When the code is written correctly but something goes wrong while it runs, Python raises an exception. If the exception is not caught, the program stops and Python shows a “traceback” — an error report:

Text
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print(10 / count)
ZeroDivisionError: division by zero
ExceptionWhen it happensExample
ValueErrorthe type is right but the value is unsuitableint('abc')
TypeErrorthe operation is not possible for this type'5' + 5
ZeroDivisionErrordivision by zero10 / 0
IndexErrorthere is no such index[1, 2][5]
KeyErrorthe dictionary has no such key{}['a']
NameErrorno variable has this nameprint(scor)

try and except

We put code that might fail inside a try block. If an exception happens, Python skips the rest of the try block and jumps to the matching except block. After that, the program continues normally.

Python
text = 'abc'
try:
    number = int(text)
    print('Number:', number)
except ValueError:
    print('That is not a number!')
print('The program continues.')
▸ Expected output
That is not a number!
The program continues.
Set text to '25' and compare the result.

One try can have several except blocks — each catches its own type of exception. Writing except ... as e stores the exception itself in the variable e; if you print it, you see Python's explanation.

Python
def safe_divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        print('Cannot divide by zero!')
    except TypeError as e:
        print('Wrong type:', e)
    return None

print(safe_divide(10, 2))
print(safe_divide(5, 0))
print(safe_divide(5, 'x'))
▸ Expected output
5.0
Cannot divide by zero!
None
Wrong type: unsupported operand type(s) for /: 'int' and 'str'
None

else and finally

  • The else block runs only if the try block finished without an error — put the work with the successful result there.
  • The finally block always runs — whether there was an error or not. It is usually used to wrap things up: closing a file, writing a message.
Python
for value in ['42', 'seven']:
    try:
        n = int(value)
    except ValueError:
        print(f'{value}: not a number')
    else:
        print(f'{value}: doubled is {n * 2}')
    finally:
        print('checked', value)
▸ Expected output
42: doubled is 84
checked 42
seven: not a number
checked seven

raise: raising your own exception

Sometimes everything is fine for Python but not for your program: for example, an age cannot be negative. In such cases you can raise an exception yourself with raise. The code below imitates a user's answers and accepts the first valid age:

Python
answers = ['abc', '-3', '14']
for answer in answers:
    try:
        age = int(answer)
        if age <= 0:
            raise ValueError('age must be positive')
    except ValueError as e:
        print(f'Bad input {answer}: {e}')
    else:
        print('Accepted age:', age)
        break
▸ Expected output
Bad input abc: invalid literal for int() with base 10: 'abc'
Bad input -3: age must be positive
Accepted age: 14
Exercise

Convert the strings in data to numbers with int() and add them up. The program must not stop on an item that cannot be converted: catch the error with try/except ValueError and print Skipped: followed by that item. At the end print Total: and the sum.

Exercise · Python
data = ['12', 'seven', '30', '4.5', '8']
total = 0
# for each item: try to add int(item) to total,
# on ValueError print Skipped: and the item
# print Total: and total
▸ Expected output
Skipped: seven
Skipped: 4.5
Total: 50
Exercise

A warehouse has 100 notebooks. Write a function sell(stock, count) that raises ValueError('count must be positive') if count is zero or negative, raises ValueError('not enough in stock') if it is more than the stock, and otherwise returns how many are left. The loop in the starter code tries every sale with try/except — do not change it.

Exercise · Python
# define sell(stock, count) here

stock = 100
for count in [30, -5, 90, 50]:
    try:
        stock = sell(stock, count)
        print('Sold', count, '- left:', stock)
    except ValueError as e:
        print('Error:', e)
▸ Expected output
Sold 30 - left: 70
Error: count must be positive
Error: not enough in stock
Sold 50 - left: 20

Key points

  • An exception is an error that happens while the program runs; if it is not caught, the program stops.
  • try holds the risky code, and except catches a specific exception.
  • else runs only when there was no error; finally always runs.
  • You can raise your own exception with raise: raise ValueError('...').
  • The last line of a traceback shows the exception type and the reason.

Check yourself

10 questions. Every correct answer earns XP.

1 / 10
Which exception does int('hello') raise?