A JSON text must at least contain two octets

75,232

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:

  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. :-)

Share:
75,232
Cory
Author by

Cory

Hi

Updated on February 20, 2020

Comments

  • Cory
    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 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: 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
    Cory over 12 years
    Yes, although I'd need to repeat this everywhere I attempt to parse. Perhaps I should submit a patch.
  • Alex Wayne
    Alex Wayne over 12 years
    Added 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
    RSG about 11 years
    @Alex Where would you deploy the mini patch to catch this across the entire app?
  • Mike Campbell
    Mike Campbell over 9 years
    This 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
    Mr. Demetrius Michael over 8 years
    @AlexWayne why not JSON.parse(json) if json.is_a?(String) && json.length >= 2
  • Amol Pujari
    Amol Pujari about 7 years
    better to do json = json.to_s.strip before accepting it inside parse_nil
  • Dan
    Dan over 6 years
    This 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
    calasyr over 5 years
    I think it's stringified.
  • Yossi
    Yossi about 4 years
    Forgive 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
    Yossi about 4 years
    Forgive 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
    Alex Wayne about 4 years
    @Yossi no that's just an example of how to use the method.
  • Yossi
    Yossi about 4 years
    So what do I need to write there?