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



我使用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"之类的话,那就太棒了。这可能吗?

我不太确定我是否理解你的实际问题是什么…

你得到了Java.lang.RuntimeException: Unable to parse MyClass json: LeftProjection(Left(String: CursorHistory(List()))),因为sys.error就是这么做的。

使用方法Parse.decodeEither时,生成的类型为Either[String, MyClass]。有很多方法可以检查或使用"非此即彼"进行操作。其中一个,你已经在使用:检查结果是否在任何一边,并根据它采取行动

不过,一种更惯用的方法是将其折叠起来:

parsed.fold(
error => //do something with error,
myclass => //do something with myclass
)

从Scala2.12来看,Either是右偏的Monad,这意味着你可以在一个理解中使用它,它会在右手边平面化Map。我认为阅读它的文档可能会有所帮助。

我同意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)))

最新更新