|Previous Lesson||Table of Contents||Next Lesson|
When code executes, errors can occur. For example, if you could have invalid syntax:
cat is missing an ending quotation mark, leading to this error:
SyntaxError: EOL while scanning string literal
Here’s the error you get when you try to divide a number by zero:
ZeroDivisionError: division by zero
You sometimes might want to raise an error yourself. For example, suppose you have a function that doesn’t accept the input of 1, you could write something like this:
def f(x): if x == 1: raise ValueError("x cannot be 1") print(x)
To raise an error yourself, use the raise keyword, followed by the name
of the error you want to raise (in this case,
ValueError) and pass in it
the error message you want to provide. Thus, when you execute something like
f(1) print("Program continued!")
ValueError: x cannot be 1
Although error message like these are useful, one disadvantage is that they
halt the execution of your code (notice how the
try-except comes in:
try: f(1) except ValueError: print("Function errored, but let's continue!") print("Program continued!")
This gets us now:
Function errored, but let's continue! Program continued!
Unlike before, we now get to the final
except statement and did not halt the program.
The purpose of the
try-except format is to give us the possibility of guarding
against potential errors that could halt our program. If no such errors occur,
the code executes as normal. For example, if we had tried:
try: f(2) except ValueError: print("Function errored, but let's continue!") print("Program continued!")
f does not raise an error, so this gets us:
2 Program continued!
When we have a
try-except statement, we can have multiple
for a single
try, just like we could have multiple
elif blocks for a single
if statement. Python checks each
except block from top to bottom, checking
to see if the error being handled matches the one that is raised. For example:
try: f(2) except TypeError: print("Function errored strangely, but let's continue anyhow!") except ValueError: print("Function errored, but let's continue!") print("Program continued!")
Note that if the error does not match to any of the ones provided, the error is raised and halts the program as before:
try: f(2) except TypeError: print("Function errored, but let's continue!") print("Program continued!")
We get the same error message as before and abort before getting to the
ValueError: x cannot be 1
Finally, it should be noted that if we just have a bare
except (i.e. one
without any error name after it), it is considered a “catch-all” and can be
used to handle any error raised.
try: f(2) except TypeError: print("Function errored, but let's continue!") except: print("Catch all saves the day!") print("Program continued!")
This will output:
Catch all saves the day! Program continued!
Although the name
Exception might have a negative connotation, exceptions
are very useful in terms of adding more sophistication to the code that you write
by providing a true mechanism for handling errors or invalid inputs provided.
That’s it for now! Let’s answer questions to review what we learned:
How would you raise an
OSErrorwith the message: “Sorry about that! Something went wrong” ? (solution).
Create a function that accepts one argument. Have the function print
"Good input!", unless the argument is
"cat", in which case, raise a
try-exceptblock with your function by calling it with the argument
tryblock. In the
exceptblock, have it print anything that you want. After the
try-except, print something else (solution).
By the way, you may have noticed that error types are in fact classes, and their
__init__ functions almost always accept an optional parameter for the
error message that is displayed to users.
If you are comfortable with errors, feel free to move on to imports.