EDIT: This will work as you described:
try:
msg = make_msg_fancy(msg)
msg = check_for_spam(msg)
except MessageNotFancyException:
print("couldn't make it fancy :(")
except MessageFullOfSpamException:
print("too much spam :(")
When an exception occurs, it skips the rest of the try block and continues at the exception... it doesn't go back.
You are doing something like this:
for person in [{"dog": "Henry"}, {}, {"dog": None}]:
try:
doggo = person['dog'] # can throw KeyError
except KeyError:
print("Not a dog person")
continue # skip the rest of the loop (since this is a for loop)
try:
print(doggo.upper()) # can throw AttributeError
except AttributeError:
print("No doggo :(")
A better way is, as Christian suggested:
for person in [{"dog": "Henry"}, {}, {"dog": None}]:
try:
doggo = person['dog'] # can throw KeyError
print(doggo.upper()) # can throw AttributeError
except KeyError: # person dict does not contain a "dog"
print("Not a dog person")
except AttributeError: # dog entry cannot be .upper()'d
print("invalid doggo :(")
Both of which output:
HENRY
Not a dog person
invalid doggo :(
Note this will skip the second set of lines automatically if the first set fails, and lets you do different things based upon which exception occurred.
I think you're confused. After a KeyError
above, execution continues after the except
blocks. The rest of the try:
is skipped, which is what you seem to want:
That's why I can do:
try:
dct[key] += value
print("Added.")
except KeyError:
dct[key] = value
print("New key.")
Only one of those prints will happen.