A JSON text must at least contain two octets
Solution 1
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
data.presence && JSON.parse(data)
JSON.parse(data.presence || '{}')
Solution 3
According to json.org
JSON is built on two structures:
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.
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. :-)
Comments
-
Cory about 4 years
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 aTypeError
. If you convert all input usingto_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: What is a 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. -
Cory over 12 yearsYes, although I'd need to repeat this everywhere I attempt to parse. Perhaps I should submit a patch.
-
Alex Wayne over 12 yearsAdded a little mini patch to the JSON module you can use instead. It involves no crazy method aliasing magic or anything, and is easily reusable.
-
RSG about 11 years@Alex Where would you deploy the mini patch to catch this across the entire app?
-
Mike Campbell over 9 yearsThis is pretty bad as it'll rescue anything, including all the other types of parser error that you probably want to know about.
-
Mr. Demetrius Michael over 8 years@AlexWayne why not JSON.parse(json) if json.is_a?(String) && json.length >= 2
-
Amol Pujari about 7 yearsbetter to do
json = json.to_s.strip
before accepting it inside parse_nil -
Dan over 6 yearsThis is no longer true. An RFC 7159 from March 2014 updates those restrictions. All of the followings are valid JSON:
null
,false
,true
,42
,"Some string"
,{}
,[]
-
calasyr over 5 yearsI think it's stringified.
-
Yossi about 4 yearsForgive my ignorance (poor windows guy). Do I need to add the 'parsed = ...' line to my podfile? Tried that but I am getting an error (as you probably would expect...)
-
Yossi about 4 yearsForgive my ignorance (poor windows guy). Do I need to add the 'data.presence &&' and 'JSON.parse' lines to my podfile? Tried that but I am getting an error (as you probably would expect...)
-
Alex Wayne about 4 years@Yossi no that's just an example of how to use the method.
-
Yossi about 4 yearsSo what do I need to write there?