3 ms·
> Because you see, whenever you do "throw new SomeException", or in other words whenever you're using exceptions for validations of user input or flow control,
by spion 11y ago
> Because you see, whenever you do "throw new SomeException", or in other words whenever you're using exceptions for validations of user input or flow control, God kills a kitten.
> One is truly exceptional, whereas the other could be prevented
Reading this I would think that exceptions are black magic. So many ill-defined words like "truly exceptional" (true Scottsman comes to mind) and dogma (exceptions bad, mkay? no explanation required).
Seriously, what is "truly exceptional"? Its interesting if you look at the definition of "exceptional" you get "unusual; not typical", but it seems like people who are strongly against exceptions mean something else...
And "don't use exceptions for flow control" - what does that even mean? Exceptions are a form of flow control. Perhaps you want `abort` instead? That certainly can't be used for flow control...
- bad_user 11y agoTruly exceptional means nondeterministic outcomes that should never happen, yet still do because of factors outside the developer's control. This includes out of memory errors, segfaults, threads being interrupted, contract violations (incorrect usage of an API that cannot be prevented with static typing, but this does NOT include validating the user's input), file handlers not being opened because you reached the limit forced by the OS, running out of Inodes or space on the local hard-disk, network sockets becoming unresponsive because the network is temporarily down, requests timing out, etc. > So many ill-defined words like "truly exceptional" (true Scottsman comes to mind) and dogma (exceptions bad, mkay? no explanation required). Not sure what the "true Scottsman" has to do with it, maybe you can explain. At this point I wrote over 500 words to explain myself on an internet forum, without debating the finer details of the English language, but we can do that as well.
- spion 11y ago> incorrect usage of an API that cannot be prevented with static typing, but this does NOT include validating the user's input This is the part I have the most contention with. Take parsing JSON for example: there are many situations in which you pretty much know that the input being invalid is truly exceptional (reading a local file generated by some part of the code, for example). There are others however where its not exceptional at all (reading incoming input from a user). So its up to the API consumer, not the producer to decide whether a situation is "truly exceptional" or not. Exceptions recognise this, and let the errors propagate through the layers so that each layer can decide whether the error is exceptional from their point of view.
- bad_user 11y agoParsing JSON can produce a finite set of errors that you know about. Such errors are either lexer/parser errors (invalid token encountered, expecting a string and getting something else) or format errors (expecting a DateTime inside a string). One possible type that could express this, copied from Play's JSON, would be this one: sealed trait JsResult[+A] case class JsError(errors: Seq[(JsPath, Seq[ValidationError])]) extends JsResult[Nothing] case class JsSuccess[+A](value: A, path: JsPath) extends JsResult[A] So instead of throwing exceptions, you return a JsResult that could represent one or multiple errors. > So its up to the API consumer, not the producer to decide whether a situation is "truly exceptional" or not. We kind of agree on this one, as long as we are talking about things the producer can control of course. The producer obviously can't guard well against a hard-disk getting full (and that would be truly exceptional). But for things it can control, the producer shouldn't throw exceptions on JSON parsing, when it could return a JsResult and leave the consumer to decide what to do with it. And the advantage is that JsError is explicit, its shape is explicit, so the consumer knows exactly what happened and it can return a human-readable error message, or it can fall-back to something else, etc. And then, if you read from a file generated by your software and you expect a valid JSON and it's not what you expect, then that's obviously a bug, which is also an exceptional situation, so exceptions are OK. But that's no longer user input, as you've said.
- azernik 11y agoAbsolutely agree. I think the Play JSON libraries are a good example of leaving that distinction to the user: you can either do jsonValue.as[SomeParsedType] when you want an exception, or jsonValue.validate[SomeParsedType] if you want to keep JsErrors in the normal flow of control. The language makes it very clear. (I tend to use .as() in practice, but in part that's because in the Try[X]/Future[X]/Either[T, X]/etc. monads exceptions work a lot like early returns, which is a nicely-bounded deviation from structured programming that I'm pretty okay with).