Python Exceptions
By Flavio
Published · Updated
Tagged: Python
Learn how exception handling works in Python with try, except, else, and finally blocks, how to raise your own errors, and how to define a custom exception.
It’s important to have a way to handle errors.
Python gives us exception handling. When something goes wrong, Python raises an exception. If nobody catches it, the program prints a traceback and stops.
try and except
You wrap the risky lines in a try block. If an error occurs, Python looks for an except block that matches that error:
try:
result = 2 / 0
except ZeroDivisionError:
print('Cannot divide by zero!')
Without the try, this program terminates:
result = 2 / 0
print(result)
Traceback (most recent call last):
File "main.py", line 1, in <module>
result = 2 / 0
~~^~~
ZeroDivisionError: division by zero
and the lines after the error will not be executed.
The specific error depends on the operation. Open a file that does not exist and you get a FileNotFoundError. Call input() and hit the end of input and you get an EOFError. File read() and readline() return an empty string at EOF. Divide by zero and you get a ZeroDivisionError. Convert a bad string like int('abc') and you get a ValueError. Use the wrong type, like '1' + 1, and you get a TypeError.
You can handle more than one error, each with its own block:
try:
age = int('twelve')
except ValueError:
print('That is not a number')
except TypeError:
print('Give me a string or a number')
Python checks the except blocks from top to bottom and runs the first match. Then it skips the rest.
To catch all remaining exceptions you can use except without a type:
try:
result = 2 / 0
except ZeroDivisionError:
print('Cannot divide by zero!')
except:
print('Something else went wrong')
That bare except: also catches KeyboardInterrupt and SystemExit. In practice use except Exception: (or except Exception as error:) so Ctrl-C still stops the program, and be as specific as you can.
as error gives you the exception object, so you can print the message or log it:
try:
result = 2 / 0
except Exception as error:
print(error)
else and finally
The else block runs only if no exception was raised:
try:
age = int('8')
except ValueError:
print('That is not a number')
else:
print('Age is', age)
Use else for the success path. Keep try small: only the line that might fail. That way a bug in the success code does not get swallowed by your except.
A finally block runs in any case, whether an error occurred or not:
try:
result = 2 / 0
except ZeroDivisionError:
print('Cannot divide by zero!')
finally:
result = 1
print(result) # 1
finally is the right place for cleanup: close a file, release a lock, disconnect. It runs even if you return from the try or except. For files, with open() does that cleanup for you, so you rarely write try/finally around open().
Raising exceptions
You can raise exceptions in your own functions, too, using the raise statement:
raise Exception('An error occurred!')
This raises a general exception, and you can intercept it using:
try:
raise Exception('An error occurred!')
except Exception as error:
print(error)
Raise an exception when the caller needs to know something went wrong. Return a normal value (None, False, 0) when a missing result is an expected outcome, not a failure.
You can also define your own exception class, extending from Exception:
class DogNotFoundException(Exception):
pass
passhere means “nothing” and we must use it when we define a class without methods, or a function without code, too.
try:
raise DogNotFoundException()
except DogNotFoundException:
print('Dog not found!')
A custom exception is useful when the caller should treat your error differently from a generic Exception. DogNotFoundException is easier to catch than a message string on a plain Exception.
Want me to talk about your product? You can sponsor this site.
Related posts about python: