Обнаружение искаженного JSON в NodeMCU Lua с помощью sjson.decode()

#json #lua #esp8266 #nodemcu #panic

#json #lua #esp8266 #nodemcu #паника

Вопрос:

Использование NodeMCU (последняя версия) на ESP-12S

Я пытаюсь проанализировать предоставленный пользователем JSON и что-то с ним сделать. Однако, поскольку JSON предоставляется пользователем, я не могу гарантировать его достоверность. Поэтому я хочу сначала проверить, искажен ли входной JSON или нет, прежде чем продолжить.

Я использовал следующий код:

 function validatejson(input)
    
    if sjson.decode(input) then
        return true
    end

end
 

Таким образом, успешным примером может быть:

 x = '{"hello":"world"}'

print(validatejson(x))

--> true
 

и неудачный пример был бы:

 x = '{"hello":world"}'

print(validatejson(x))

--> nil
 

Вышеупомянутая функция работает, однако при использовании этого в моем соответствующем коде она выдает ошибку ПАНИКИ и перезапускается:

  PANIC: unprotected error in call to Lua API: Incomplete JSON object passed to sjson.decode
 

Итак, как вы, вероятно, тоже сделали бы, я решил использовать pcall() функцию, которая возвращает ошибку как логическое значение (false означает, что в вызове не было ошибки):

 function validatejson(input)
    
    if not pcall(sjson.decode(input)) then
        return true
    end

end
 

Все еще не повезло! 🙁

Есть идеи, как успешно обнаружить искаженный JSON в Lua с помощью NodeMCU?

Комментарии:

1. Если вы используете библиотеку cjson lua, то используйте local cjson = require "cjson.safe" . При использовании cjson.decode() он вернет nil для не поддающихся анализу искаженных ошибок JSON. Такой подход предотвратит броски. При cjson.safe этом он возвращает nil значение, которое вы можете проверить в результате.

Ответ №1:

     if not pcall(sjson.decode(input)) then
        return true
    end
 

Это неправильно: вы вызываете только pcall результат sjson.decode(input) , поэтому ошибка произойдет раньше pcall . Правильный способ сделать это:

 local ok, result = pcall(function()
   return sjson.decode(input)
end)
return ok -- might as well return result here though