Вернуть ошибки проверки гранита в формате JSON
У меня есть гранит User
модель с некоторыми проверками. Когда кто-то делает POST
запросить users/new
Я хотел бы вернуть ошибки проверки (если таковые имеются) в виде JSON. В настоящее время у меня есть:
if user.errors.size > 0
halt env, status_code: 500, response: user.errors.to_json
end
Но когда я пытаюсь скомпилировать, я получаю:
in /usr/local/Cellar/crystal/0.26.1/src/json/to_json.cr:66: no overload
matches 'Granite::Error#to_json' with type JSON::Builder
Overloads are:
- Object#to_json(io : IO)
- Object#to_json()
each &.to_json(json)
^~~~~~~
1 ответ
Так что проблема в том, что User#errors
является Array(Granite::Error)
т.е. Array
держа Granite::Error
s. К сожалению, это не похоже на Granite::Error
реализует to_json(JSON::Builder)
метод (то есть метод to_json
принимая параметр типа JSON::Builder
), который Array#to_json
опирается на (этот фрагмент, который вы видите, есть от реализации Array#to_json
который вы можете посмотреть на GitHub.).
Я бы порекомендовал создать JSON самостоятельно, используя JSON.build
, Это имеет дополнительный побочный эффект, заключающийся в том, что JSON, с которым вы отвечаете (который, как мне кажется, используется некоторым клиентом), полностью находится под вашим контролем. Если бы разработчики Granite должны были изменить способ кодирования Granite::Error
с в JSON, и вы использовали их to_json
метод, изменение не вызовет ничего во время компиляции.
Как примечание, я бы рекомендовал не использовать код состояния 500 для обозначения ошибки проверки, так как обычно она зарезервирована для непредвиденных ошибок внутри вашего сервера. Ошибка 4xx (например, 400 - неверный запрос) была бы более подходящей. В качестве второго примечания было бы более полезно POST
быть сделано в /users
конечная точка, в отличие от /users/new
,
С этими изменениями здесь будет получен фрагмент:
if user.errors.size > 0
errors_as_json = JSON.build do |json|
json.array do
user.errors.each do |error|
json.string error.to_s
end
end
end
halt env, status_code: 400, response: errors_as_json
end