Exception handling in Python can sometimes feel like a Wild West. If you have a `send_email` function, and the caller inputs an invalid email address, should it:
A) Return `None` or some other special return value,
B) Let the underlying exception it might cause bubble up,
C) Check via a regex and type checking and raise a `ValueError` immediately, or
D) Make a custom `EmailException` subclass and raise that?
What if there is a network error while the email was sending? Or what if the function calls a helper `_format_email` that returns an integer (clearly wrong!), or raises an `TypeError` itself? Should it crash the program or prompt a retry?
This talk will introduce the concept of an exception, explain the built-in Python exception hierarchy and the utility of custom subclasses, demonstrate try/except/finally/else syntax, and then explore different design patterns for exception control flow and their tradeoffs using examples. It will also make comparisons to error handling philosophy in other languages, like Eiffel and Go.