使用Argonaut和自定义编解码器解析JSON时如何获得更好的错误消息

时间:2018-11-16 14:51:07

标签: scala 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())))

处理解码错误的正确方法是什么?

编辑:我的问题不是如何处理提供的错误消息。如果Argonaut可以说诸如“解析位置X处的错误,意外成员y”之类的话,那将是伟大的。有可能吗?

2 个答案:

答案 0 :(得分:0)

我不确定我是否理解您的实际问题是什么...

您将获得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是右偏Monad,这意味着您可以在理解中使用它,它将FlatMap放在右侧。 我认为阅读其docs可能会有所帮助。

答案 1 :(得分:0)

我同意Argonaut解码错误可能会比较简短,但它们也很有意义。注意CursorHistory对象。它提供了解码期间的最新操作。

在您的情况下,由于CursorHistory为空的List,因此您似乎无法解析JSON。

简单示例(未经测试):

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)))