I’m curious how folks are handling a specific class of errors related to JSONItem: when the key exists, but the value is not the expected type. For example, you’re expecting a string but get an object, or vice versa.
If you are reading untrusted input and trying to do full validation, this can be challenging.
For example, if SAMPLE is the following JSON:
{
"a": 10,
"b":
{
"x": 1
},
"c":
[
1,
2,
3
],
"d": "d"
}
Here are some examples of the type errors I’m interested in:
var root as JSONItem
var item as JSONItem
var value as Variant
var num as Double
var s as String
root = new JSONItem(SAMPLE)
' What happens if you ask for a child but it's not a child?
item = root.Child("a") // raises IllegalCastException
item = root.Child("d") // raises IllegalCastException
' Expect a numeric value, but get an object
value = root.Value("b") // returns a JSONItem
num = value.DoubleValue // raises TypeMismatchException
' Expect a string, but get an array
value = root.Value("c") // returns a JSONItem
s = value.StringValue // raises TypeMisMatchException
' Expect a number, but get a string
num = root.Value("d").DoubleValue // returns 0
It would be nice to have a clean way to check that a given key not only exists, but is a particular type, prior to requesting it, since requesting via .Child or .Value forces you to first make an assumption about the type of the key’s value, and as shown above, if that assumption is wrong, it’ll lead to an exception.
Currently I know of three approaches to deal with this and I’m curious if there are others people are using.
- Wrap all
JSONItemparsing code in a try/catch block. This seems the simplest way to say “I’m expecting data in a specific format and anything else is an error.” Also handles missing keys. This is still susceptible to silent type-conversion errors like expecting a number and getting a string. - Use
.Lookupinstead of.Child/.Valueand type-check the result. If that call returns an object I think it’s safe to assume it’s a childJSONItem; otherwise the variant result is a value and can be type-checked. - Use
ParseJSONand deal with dictionaries. My sense from this forum is that folks preferJSONItemin general for a variety of reasons.
I wonder if it would be useful to add something like JSONItem.Type(key) that returns an enum of possible JSON types (object, array, string, number, boolean, null). This would allow some type-checking before requesting the actual value and could inform a decision about whether to use .Child or .Value.