Как получить лучшие сообщения об ошибках при разборе JSON с Argonaut и пользовательскими кодеками
Я использую Argonaut для анализа JSON с моими пользовательскими кодеками. Мой код выглядит так:
val json: String = ...
val parsed = Parse.decodeEither[MyClass](json)
val checks = if (parsed.isRight) parsed.right.get
else sys.error("Unable to parse MyClass json: " + parsed.left)
Тем не менее, я никогда не получаю никаких полезных сообщений об ошибках. Все, что я получаю, это java.lang.RuntimeException: Unable to parse MyClass json: LeftProjection(Left(String: CursorHistory(List())))
,
Как правильно обрабатывать ошибки декодирования?
Изменить: мой вопрос не в том, что делать с предоставленным сообщением об ошибке. Было бы здорово, если бы Аргонавт мог сказать что-то вроде "Ошибка разбора в позиции X, неожиданный член y" или что-то в этом роде. Это возможно?
2 ответа
Я согласен, что ошибки декодирования Argonaut могут быть немного краткими, но они также имеют смысл. Обратите внимание на объект CursorHistory. Это обеспечивает самую последнюю операцию во время декодирования.
В вашем случае, похоже, что вы не можете проанализировать JSON, так как CursorHistory
пустой List
,
Простой пример (не тестировался):
case class Person(name: String, age: Int)
object Person {
implicit def PersonCodecJson: CodecJson[Person] =
casecodec2(Person.apply, Person.unapply)("name", "age")
}
Персона JSON:
{
"name": "Fred"
}
Ошибка разбора приведенного выше примера будет выглядеть примерно так: CursorHistory(List(El(CursorOpDownField(age),false)))
,
Я не совсем уверен, понимаю ли я, каков твой настоящий вопрос...
Вы получаете Java.lang.RuntimeException: Unable to parse MyClass json: LeftProjection(Left(String: CursorHistory(List())))
потому что это то, что sys.error
делает.
Когда вы используете метод Parse.decodeEither
результирующий тип Either[String, MyClass]
, Есть много способов проверить или использовать Either. Один из них вы уже используете: проверяете, есть ли результат с обеих сторон, и действуйте на его основе.
Тем не менее, более идиоматический подход - это сложить:
parsed.fold(
error => //do something with error,
myclass => //do something with myclass
)
Из Scala 2.12, Either
это монада с правым смещением, что означает, что вы можете использовать ее для понимания, которое будет отображаться поверх правой стороны. Я думаю, что чтение его документов может быть полезным.