Meredith Montgomery <mmontgom...@levado.to> writes: > I'm trying to show people that exceptions are a very nice thing to have > when it comes to detecting when something went awry somewhere. I'd like > a real-world case, though.
Here's my contribution. I want to handle all errors in main() and the real job is done in does_a_job(), which, in turns, needs to delegate tasks to those other procedures that fail sometimes. It's does_a_job() that /must/ distinguish the error codes because errors come in as False from both opens_file() and reads_file(). So the checks must be done both in does_a_job() and in main(). (We also notice that does_a_job() has a return-type that's a union (sometimes an integer, sometimes a string), which makes distinguishing error code and success a bit harder.) --8<---------------cut here---------------start------------->8--- from random import randint def main(): r, data = does_a_job() if r < 0: if r == -1: print("Fatal. Could not open file.") return None if r == -2: print("Fatal. Could not read file") return None print(f"Great! We got the data: ``{r}''.") def does_a_job(): okay = opens_file() if not okay: return -1 okay, data = reads_file() if not okay: return -2 closes_file() return data def open_file(): # Opens okay with probability 80% return randint(1,10) <= 8 def read_file(): # Reads okay with probability 50% return randint(1,10) <= 5, "data I am" def closes_file(): # Works with probability 1 return True --8<---------------cut here---------------end--------------->8--- If we could give the program a final destination at does_a_job(), the job would be easier. But all we want to do in does_a_job() is to propagate the error conditions upwards to main() to really decide what to do. Exceptions lets us do that with a cleaner version. --8<---------------cut here---------------start------------->8--- from random import randint def main(): try: data = does_a_job() except FileNotFoundError: print("Fatal. Could not open file.") except MemoryError: print("Fatal. Could not read file") else: print(f"Great! We got the data: ``{data}''.") def does_a_job(): open_file() data = reads_file() close_file() return data def open_file(): # Opens okay with probability 80% if randint(1,10) <= 8: return True raise FileNotFoundError("Sorry: the file system is /so/ busy right now.") def reads_file(): # Reads okay with probability 50% if randint(1,10) <= 5: return "data I am" raise MemoryError("Sorry: not enough memory for /all/ this data.") def close_file(): # Works with probability 1 return True --8<---------------cut here---------------end--------------->8--- -- https://mail.python.org/mailman/listinfo/python-list