On Fri, May 01, 2020 at 11:36:40AM +0300, Ram Rachum wrote:
I thought of a third advantage to this approach: Except clauses will be easier to understand.
If I'm reading someone's code and I see `except ValueError`, I'm gonna have to do a bit of thinking to figure out what exactly they're catching.
You say that as if that's a bad thing. Except in the most blindingly obvious and simple cases, you're going to have to do that anyway. Working out what is being caught is not the hard part, unless you abuse try...except clauses: try: main() except: print("an error occurred") is a classic example of exception misuse. But there are many smaller ways to abuse them too. The hard part is usually figuring out *why* the exception occurred, not *what* you are catching.
On the other hand, if the code is `except IntParsingError`, then I know exactly what it is they're catching.
Will you? Since I don't know what functions might raise IntParsingError, I can't tell what it might have raised it. I mean, sure, it is obviously something parsing an int in some sense, but that's pretty wide: - must it be parsing a string? could it be bytes? - parsing a fraction? - might it be a call to `eval` or `compile` or only `int`? I think we need to distinguish between the two use-cases for exceptions: - to halt processing and report an error to the developer; - to be caught and recovered from. In this case, I don't think there is any benefit to me, the developer, to read: IntParsingError: invalid literal for int() with base 10: 'a' over the status quo: ValueError: invalid literal for int() with base 10: 'a' and from the perspective of debugging, it's just bloat: - one more thing to document - one more thing for the test suite to test - one more thing to learn - one more thing to misspell (is it IntParsingError or IntParseError or IntParsingException?) - one more class using up memory - one more thing for IDEs and syntax colourisers to check for etc. From the perspective of catching and recovering from errors, again, I doubt that there is much benefit to well-written code: try: num = int(astring) except ValueError: recover() is fine, changing the ValueError to IntParsingError gains nothing. The only advantage I can see is if your try block falls into that very narrow zone where it is large enough to contain *exactly* one attempt to parse an int *but also* at least one other function call which might raise an unrelated ValueError: try: a, b = int(astring), float(alist) except IntParsingError: ... But I'm not sure that this is valuable enough to make up for the bloat. -- Steven