Как получить лучшие сообщения об ошибках при разборе 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 это монада с правым смещением, что означает, что вы можете использовать ее для понимания, которое будет отображаться поверх правой стороны. Я думаю, что чтение его документов может быть полезным.

Другие вопросы по тегам