4 ms·
> I much prefer php's json_decode function, since it just returns `null` on invalid input. A function which has the same result in case of an error as when gi
by pilif 15y ago
> I much prefer php's json_decode function, since it just
returns `null` on invalid input.
A function which has the same result in case of an error as when given valid input (hint: 'null' is a valid json string) is neither good design, nor something I would actually 'prefer'.
Aside of that (and more to the point of the original article), I do believe that exceptions can be very useful the deeper the abstraction of your libraries gets.
If you are 'far down' the stack and you want to ensure that you are in a position where it's safe to proceed and making it very, very clear for the caller that something went wrong, trow() is the perfect tool in order not to be called with a garbage argument on a successive call to a different function (hint: error results tend to get ignored).
And if you are a user of a library, getting nice exceptions can be very handy too - sometimes even wrapping and re- throwing them.
A very good example of real code: In a command line script which processes a lot of text-data to import into a database delegates to various importer classes depending on import line type.
All these importer classes do their thing and whenever they come across an issue, they just throw an ImporterException with all the context that they know about.
The parent script only has to deal with one single case of Exception to produce nice error messages and show everything about the context where they happened.
I can make the importers as complicated as they need to be and I never have to check a single return value (or forget to check it). There is one central place to handle whatever kind of Error that can creep up.
This is very handy.
Granted, in JS/node where each callback cleans out the stack so that a thrown exception can't be handled by whatever caused the callback to be executed later), exceptions are useless and actually harmful because they can mess up the program flow (which assumes callback to be triggered eventually).
But exceptions being useless in one environment doesn't make the useless everywhere.
- Dylan16807 15y agoIt was pointed out later in the thread that it should have been 'undefined' rather than 'null'.
- dkersten 15y agoI'm genuinely curious: how is returning undefined any different from returning null, in this case?
- pilif 15y agoIf you return null, there is no way to discern between invalid input data and 'null' as input. If you return null for 'null' as input and undefined for invalid data, then you don't have to look at the input again to check whether you just failed to parse json or whether the input was just 'null'. if (HypotheticalJSON.parse(input) === null && input.trim() != 'null'){ alert('invalid input'); } instead of just if (HypotheticalJSON.parse(input) === undefined){ alert('invalid input'); } Though as I said in my comment, I do believe throwing an exception to be a valid action here - at least in any other environment than server-side JS where you have to be a bit careful.
- dkersten 15y agoOk, so its the case that null is valid data and makes for a bad "invalid value". Personally, this demonstrates a core reason why return values (and returning null in particular, in any language) are a bad way of handling errors - they're a leaky abstraction and too much inside knowledge is required to use them safely. For example, if I have code like a = foo() if (a is valid) bar(a) I have to know about the possible values of a before I can pass it to bar. Exceptions are better because I don't have to know the internal details (foo and bar could be library functions that return some data I don't know all the valid values of): try { a = foo() bar(a) } catch (e) { handle error here } But I also agree with the post that exceptions aren't always great either. Instead of returning null, I like haskells Maybe. You either return a valid value (which can be null, in this case) or it returning Nothing, which can never be something which is also valid data. This removes the possible ambiguity of whether null is an error value or a valid value and the haskell compiler makes sure you hanbdle the error case, but its still a signal-error-through-return-value method of error handling and is not always ideal. I also like the ideas behind common lisps condition system, though I have never used it in real code. I like the idea of abstracting the error signalling, handling and routing into separate entities that can happen at various parts of the hierarchy. I also like Go's defer/panic/recover mechanism, though, again, I have never used it in real code, so don't know how well it works in reality.
- Daniel_Newby 15y ago
- rue 15y agoI'm not keen on exposing undefined to external code; it inflates it into a “valid” value like null has become.
- Periodic 15y agoI thought a JSON document had to have either a top level object or array, which would make a bare null an invalid JSON text. Granted, we might not be that strict all the time. See section 2, paragraph 2: http://www.ietf.org/rfc/rfc4627.txt?number=4627 http://www.ietf.org/rfc/rfc4627.txt?number=4627
- deleted 15y ago[deleted]
- davisp 15y agoThe issue with the JSON spec is that it's deceptively simple. For instance, this particular issue comes up relatively often. As you point out it's quite specific that a valid "JSON text" has a top level object or array. This assumption is even required for the sections on "detecting character encodings" (which makes me wince to this day). The particular issue is that the spec refers to "JSON text" (which no one ever uses in practice) as well as "JSON value" which is what everyone expects. The difference being that a "JSON value" is any of the 'bare' types (null, boolean, number, string, object, or array). A quick survey of JSON parsers will show you that most will accept any of these types at the top level. The one notable exception I'm aware of is Ruby's JSON library (the default one? I'm not so hip to the Ruby). Notably, though, is that the major JavaScript interpreters don't enforce this constraint (Nor do Python or YAJL (kinda) or Erlang (even the ones I didn't write)). Don't bother asking me about invalid combining characters as \u escapes. You wouldn't like me when I get the rage eyes.
- IsaacSchlueter 15y agoIt doesn't really matter what the "this is not valid json" return value is. I just don't think that it's worth the cost of capturing a bunch of stack frames for such a common occurrence as "you posted bad data to my web service".