J'ai reçu cette erreur et je n'ai pas trouvé de réponse raisonnable à cette question, j'ai donc pensé écrire un résumé du problème.
Si vous exécutez cet extrait dans irb:
JSON.parse( nil )
Vous verrez l'erreur suivante:
TypeError: can't convert nil into String
Je m'attendais à ce que la fonction renvoie nil
, et non un TypeError
. Si vous convertissez toutes les entrées à l'aide de to_s
, vous verrez alors l'erreur d'octet:
JSON::ParserError: A JSON text must at least contain two octets!
C'est très bien et bien. Si vous ne savez pas ce qu'est un octet, lisez cet article pour un résumé et une solution: Qu'est-ce qu'un octet JSON et pourquoi en faut-il deux?
Solution
La variable que vous transmettez est une chaîne vide. N'essayez pas d'utiliser une chaîne vide dans le JSON.parse
méthode.
Question
Donc, maintenant que je connais la cause de l'erreur, quel modèle dois-je utiliser pour gérer cela? Je suis un peu réticent à patcher la bibliothèque JSON pour autoriser les valeurs nil
. Toutes les suggestions seraient grandement appréciées.
parsed = json && json.length >= 2 ? JSON.parse(json) : nil
Mais vraiment, la bibliothèque devrait être capable de gérer ce cas et de retourner nil. Les navigateurs Web avec prise en charge JSON intégrée semblent fonctionner comme vous vous y attendez après tout.
Ou pour le faire avec un mini patch peu intrusif:
module JSON
def self.parse_nil(json)
JSON.parse(json) if json && json.length >= 2
end
end
parsed = JSON.parse_nil(json)
data.presence && JSON.parse(data)
JSON.parse(data.presence || '{}')
Selon json.org
JSON est construit sur deux structures:
Une collection de paires nom/valeur. Dans diverses langues, cela est réalisé sous la forme d'un objet, d'un enregistrement, d'une structure, d'un dictionnaire, d'une table de hachage, d'une liste à clés ou d'un tableau associatif.
Une liste ordonnée de valeurs. Dans la plupart des langues, cela est réalisé sous la forme d'un tableau, d'un vecteur, d'une liste ou d'une séquence.
Ainsi, au moins deux octets (8 bits) requis au niveau supérieur seraient {}
ou []
OMI, la meilleure solution serait de s'assurer que l'argument de JSON.parse
est soit un objet strigifié, soit un tableau strigifié. :-)
hash = JSON.parse(json) rescue {}
array = JSON.parse(json) rescue []
string = JSON.parse(json) rescue ''