Handling Exceptions¶
Raising Exceptions¶
You can create errors with your own messages that stop the program:
raise ValueError("expected a valid Pokemon name")
Catching Exceptions¶
The try.. except clause allows your program to catch errors and act
on them instead of terminating the program.
cards = "234567890JQKA"
for card in cards:
try:
number = int(card)
print(f"dealt {card}")
except ValueError:
print(f"{card} could not be dealt")
How not to catch Exceptions¶
Exceptions should always be caught with an explicit error type.
Using a generic except makes debugging difficult:
cards = "234567890JQKA"
for card in cards:
try:
number = int(card)
print(f"dealt {car}")
except:
print(f"{card} could not be dealt")
In this example, car causes a NameError for every card. You
don’t get any clues what exactly went wrong.
This is called the “diaper pattern” and considered a very bad habit.
What Exceptions to catch¶
File operations
web operations
big function calls
database operations
NEVER CATCH everything
Creating your own Exceptions¶
You can define your own types of Exceptions:
class WrongInputError(Exception): pass
and raise them:
text = input("please enter a number between 1-4: ")
if not text in "1234":
raise WrongInputError("{} is not a number between 1-4.".format(text))
The try..except works for your own Exception types as well.
Detailed traceback¶
Sometimes you may want to output very detailed information in an except block:
"""
Example:
Print the state of all variables when an Exception occurs.
"""
import sys, traceback
def print_exc():
tb = sys.exc_info()[2]
while tb.tb_next:
# jump through execution frames
tb = tb.tb_next
frame = tb.tb_frame
code = frame.f_code
print("Frame %s in %s at line %s"%\
(code.co_name,
code.co_filename,
frame.f_lineno))
# print local variables
for k, v in frame.f_locals.items():
print("%20s = %s"%(k,str(v)))
try:
a = 3
b = "Carrots"
c = a / 0
except ZeroDivisionError:
print_exc()