4 ms·
Can you provide some examples of specific situations in which throwing objects not derived from Error causes difficulty? I ask for two reasons. First, because
by mcherm 5y ago
Can you provide some examples of specific situations in which throwing objects not derived from Error causes difficulty?
I ask for two reasons. First, because I find argument from authority to be a very annoying logical fallacy. I have actually heard people argue that in Python one should never use an exception to exit a loop, because "that's not how exceptions are supposed to be used". The people making this argument don't realize that every for loop in Python is always exited via an exception.
My second reason for asking is that I think your examples might all fall into certain categories. For instance, maybe there is a good argument for "never throw things not derived from Error in a way that they will escape your library, but within one library/module it's a perfectly fine technique". Looking at specific pros and cons would help uncover the cases where it is most and least harmful.
- spicybright 5y ago> The people making this argument don't realize that every for loop in Python is always exited via an exception. It's just all memory addresses under the hood, so why bother with variable names? Only throwing exception objects is a layer of abstraction that makes error handling easier to handle. Nearly all python libraries follow this pattern, and it's extremely easy to pass any variable you want to your custom exception for you to handle however you want.
- shadowgovt 5y agoIf you're throwing weirdly shaped things inside code other people don't need to interface with, that's fine. Go nuts. You'll be creating a circumstance where any new person working with your code has to learn that you're doing something strange, but you won't really be impacting anybody else. The fact that JavaScript allows non-Error-derived values to be thrown means that the first thing that any code that works with a thrown value has to do to be technically correct is runtime type inspection. You can't even assume the thrown value has a stack trace attached to it. So while technically the ship has already sailed, we add further complication to everyone's error handlers when we emit non-Error values via throw... Everyone's catch code has to grow support for handling whatever Byzantine type we've decided to toss out of our code today.
- jitl 5y agoI like to have a stack trace. Please. Just in case you’re using throw for control flow inside an abstraction, if that ever leaks, anyone downstream is going to be in pain trying to figure out what is happening. You can easily attach whatever interesting values you want to an Error instance, go nuts: throw Object.assign(new Error(“suspended”), { suspend: somePromise, retriesRemaining: 4, favoriteColor: 1 })
- exfascist 5y agoThere's a very simple argument for hygiene and convention: The halting problem should make code unreadable, it doesn't largely because of hygiene and the shared knowledge formed by programmer culture. These things restrict the language to something that's just Turing complete and much easier to read. There is a such thing as legitimately unreadable code, I've had to deal with it. Usually it's abusing things like the blurry line between objects and hashmaps in languages like js and Ruby.
- mcherm 5y ago(1) I understand your point: consistently obeying sensible conventions makes code understandable and maintainable. That's a fairly good argument in favor of consistently using Error for all thrown things. (2) One unrelated point: I suspect that the halting problem doesn't prove what you think it proves. The halting problem states that one can't build a tool to reliably analyze whether a given piece of code will end or will run forever. Some people seem to believe that this means some code will be "incomprehensible" -- that no code analysis can figure out what it does. I am quite interested in the question of whether code can be made "incomprehensible" -- it has significance for things like securely protecting source code. But the halting problem would still be true even if "incomprehensible" code obfuscation is impossible and all programs can be "understood". Here's a good example of a program that might or might not halt: stop_at = input_number() x = 2 while x < stop_at: if is_prime(x) and is_prime(x + 2): break x += 1 If the twin prime conjecture is true than that program always halts. If the twin prime conjecture is false than that program is an infinite loop whenever its input is larger than the largest twin prime.