How can one check to see if a string is properly formatted in json? I am running into situations where I receive a partial json string, and then when trying to decode the erroneous string with Lua's json.decode, my application crashes.
Thanks
Note that there is a difference between crash and crash in Lua.
If you see segfaults, throw away your JSON library and use something else (there are plenty).
If you see a Lua error, just wrap JSON processing code in pcall or xpcall. (But, better, again, throw away your library, and pick a better one).
Related
A colleague and I were trying to write the minimal logic that we needed for compacting, validating, parsing, and storing json coming from a client.
Upon doing so, we realized that compacting and validating were two steps that were both being accomplished by json.Compact anyways, since the code indicates json.Compact calls the json Scanner. The scanner then validates json and errors on invalid json.
The docs do not make this explicit, but we think this is the case.
Here is a link: https://forum.golangbridge.org/t/json-compact-appears-to-also-validate-json-but-is-not-documented/23088
Let us know thoughts.
Yes.
json.Compact uses json.scanner while scanning the json. If the scanner encounters invalid JSON sets scanner.err, which is returned by json.Compact if there is an error.
This is the same way json.Valid checks for valid json, by simply scanning the JSON and checking for scanner.err.
Here's the relevant code sections:
https://go.googlesource.com/go/+/go1.16.2/src/encoding/json/indent.go#17
https://go.googlesource.com/go/+/go1.16.2/src/encoding/json/scanner.go#30
I am attempting to consume an API that I do not have control over which is somewhat poorly documentented and somewhat inconsistent. This means that sometimes, the API returns a different type than what is documented or what you would normally see. For this example, we'll look at a case when an array was returned in a place where I would normally see a string. That makes a crappy API, but my real problem is: How can I more easily track those things down? Right now, the errors look something like this:
No usable value for identifier
Do not know how to convert JArray(List(JString(3c8723eceb1a), JString(cba8849e7a2f))) into class java.lang.String
After deciphering the problem (why JValue::toString doesn't emit a JSON string is utterly perplexing to me), I can figure out the API returned an array when I made my case class only able to deal with Strings. Great. My issue is that finding this discrepancy between my object model and the contents of the JSON seems significantly more difficult than it should be.
Currently, this is my workflow for hunting down decoding errors:
Hope bad data has some sort of identifying marker. If this is not true, then it is way more guesswork and you will have to repeat the following steps for each entry that looks like the bad bits.
Go through the troubles of converting the JArray(List(JString(...), ...)) from the error message into valid JSON, hoping that I encode JSON the same way at the API endpoint I got the data from does. If this is not true, then I use a JSON formatter (jq) to format all data consistently.
Locate the place in the source data where the decoding error originates from.
Backtrack through arrays and objects to discover how I need to change my object model to more accurately represent what data is coming back to me from the API.
Some background: I'm coming from C++, where I rolled my own JSON deserialization framework for this purpose. The equivalent error when using the library I built is:
Error decoding value at result.taskInstances[914].subtasks[5].identifier: expected std::string but found array value (["3c8723eceb1a","cba8849e7a2f"]) at 1:4084564
This is my process when using my hand-rolled library:
Look at the expected type (std::string) compared with the data that was actually found (["3c8723eceb1a","cba8849e7a2f"]) and alter my data model for the path for the data in the source (result.taskInstances[914].subtasks[5].identifier)
As you can see, I get to jump immediately to the problem that I actually have.
My question is: Is there a way to more quickly debug inconsistencies between my data model and the results I'm getting back from the API?
I'm using json4s-native_2.10 version 3.2.8.
A simplified example:
{ "property": ["3c8723eceb1a", "cba8849e7a2f"] }
Does not mesh with Scala class:
case class Thing(property: String)
The best solution would be to use Try http://www.scala-lang.org/api/current/#scala.util.Try in Scala, but unfortunately json4s API cannot.
So, I think you should use Scala Option type http://www.scala-lang.org/api/current/#scala.Option .
In Scala, and more generally in functional languages, Options are used to represent an object that can be there or not (like à nil value).
For handle parsing failures, you can use parse(str).toOption, which is a function that return an Option[JValue], and you can doing a pattern matching on the resulting value.
For handling extraction of data extraction into case classes, you can use extractOpt function, to do pattern matching on the value.
You can read this answer : https://stackoverflow.com/a/15944506/2330361
I have a PHP file that is queried for information, and it passes a couple of variables back. One variable contains a JSON string with a variable in the object called message, which comes escaped to prevent it from causing issues if the message has an ampersand, single quote, etc in it.
&data={"message":"star%27s"}
Obviously the data sent is more complicated, this is just an example. After I take the data passed back by the PHP file and use URLVariables to decode it and access the "data" variable, it ends up looking like:
{"message":"star's"}
At this point I can't parse the JSON string, it will throw an error because of the single quote. Encoding it wouldn't work, it would encode more than just everything after the colon.
Is there a way to keep it from converting it? I was thinking I could manually parse the PHP returned string, but it seems unnecessary and I don't want risk running into issues later on because of it. I looked at the AS3 API and I couldn't find anything documenting this or how to disable it.
Any ideas or suggestions?
You try with
Actionscript API escape() and unescape() see for more details Escape and unescape
Also look at JSON.parse and JSON.stringify working-with-native-json-in-flash-player-11
JSON decode in actionscript see decode-json
I'm using RestSharp. I was using XML as the transport encoding for my data, but then I had problems with that, so I switched to using JSON. Now I'm having problems with that too!
All was well until I tried to pass an object containing a byte array (*). Now I get a de-serialization error complaining about "object has no parameterless constructor". (The JSON returned by the server looks Kosher - it's just not being correctly de-serialized by RestSharp).
I see I'm not the only one having problems. Is there no solution other than the baby-out-with-the-bathwater approach suggested in that post?
(*) I had tested it with a small hand-coded byte array early on in my development, just to check that it worked. It did work then, but doesn't work now. I don't know if that's due to the size of the array, the "characters" in the array, or what. Dammit, this has been such a time-sink!
For anyone else struggling with this, I ended up simply swapping out the JSON formatter in favour of JSON.NET. That works.
There are some things around the web but it's hard to tell what the standard is.
I need to do encoding and decoding. So JSON string -> AS object and AS object -> JSON string.
AFAIK, this is the standard: http://code.google.com/p/as3corelib/.
So, for instance, you can use JSON.decode(s) and JSON.encode(o) to go from string-to-object and object-to-string. I've never had a problem, except that you should wrap it in try/catch during decode because it can throw errors when the JSON is invalid.