A JSON text must at least contain two octets

JsonRuby

Json Problem Overview


I received this error, and I couldn't find any reasonable answer to this question, so I thought I'd write a summary of the problem.

If you run this snippet in irb:

JSON.parse( nil )

You'll see the following error:

TypeError: can't convert nil into String

I was kind of expecting the function to return nil, and not a TypeError. If you convert all input using to_s, then you'll see the octet error:

JSON::ParserError: A JSON text must at least contain two octets!

That's just fine and well. If you don't know what an octet is, read this post for a summary and solution: https://stackoverflow.com/questions/7200554/what-is-json-octet-and-why-are-two-required

Solution

The variable you're passing in is an empty string. Don't attempt to use an empty string in the JSON.parse method.

Question

So, now I know the cause of the error, what pattern should I use to handle this? I'm a bit loathe to monkey patch the JSON library to allow nil values. Any suggestions would be greatly appreciated.

Json Solutions


Solution 1 - Json

parsed = json && json.length >= 2 ? JSON.parse(json) : nil

But really the library should be able to handle this case and return nil. Web browsers with built-in JSON support seem to work just like you expect after all.


Or to do it with a only slightly intrusive mini patch:

module JSON
  def self.parse_nil(json)
    JSON.parse(json) if json && json.length >= 2
  end
end

parsed = JSON.parse_nil(json)

Solution 2 - Json

data.presence && JSON.parse(data)

JSON.parse(data.presence || '{}')

Solution 3 - Json

According to json.org

JSON is built on two structures:

  1. A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.

  2. An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

So, minimum two octets(8 bits) required at the top level would be {} or []

IMO, the best solution would be to make sure the argument to JSON.parse is either an strigified object or a strigified array. :-)

Solution 4 - Json

hash = JSON.parse(json) rescue {}
array = JSON.parse(json) rescue []
string = JSON.parse(json) rescue ''

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCoryView Question on Stackoverflow
Solution 1 - JsonAlex WayneView Answer on Stackoverflow
Solution 2 - JsonДенис ПрепелицаView Answer on Stackoverflow
Solution 3 - JsonSagar RanglaniView Answer on Stackoverflow
Solution 4 - JsonIchView Answer on Stackoverflow