當您收到解析錯誤時,請使用JSON.lastNoSuccess
獲取最後一個錯誤。它的類型爲JSON.NoSuccess
,其中有兩個子類,JSON.Error
和JSON.Failure
,都包含msg: String
成員詳述錯誤。 注意JSON.lastNoSuccess
不是線程安全的(這僅僅是一種全局變量)和現在已經過時(綁定在斯卡拉2.11消失)
UPDATE:很顯然,我誤以爲這不是線程安全的:它在scala 2.10之前確實不是線程安全的,但現在lastNoSuccess
由線程局部變量支持(因此在多線程上下文中安全使用)。 這樣做後,你會被原諒,認爲只要你在解析失敗在與解析(你調用parseFull
的線程)所在的線程相同的線程中讀取,那麼所有東西將按預期工作。不幸的是,這個重構過程中,他們也改變了他們如何使用lastNoSuccess
內部內Parsers.phrase
(由JSON.parseFull
調用。 見https://github.com/scala/scala/commit/1a4faa92faaf495f75a6dd2c58376f6bb3fbf44c 因爲這個重構,lastNoSuccess
重置爲None
在Parsers.phrase
末,這是沒有問題的解析器在一般情況下,爲lastNoSuccess
被用作返回作爲Parsers.phrase
反正結果的臨時值。 這裏的問題是,我們不叫Parsers.phrase
,但JSON.parseFull
,其下降的任何錯誤信息(見case None => None
裏面方法JSON.parseRaw
在https://github.com/scala/scala/blob/v2.10.0/src/library/scala/util/parsing/json/JSON.scala) 。 JSON.parseFull
錯誤的事實在scala 2.10之前,通過直接讀取JSON.lastNoSuccess
就可以很容易地避開fo,但現在該值在Parsers.phrase
的末尾重置,因此您無法從JSON
中獲取錯誤信息。
任何解決方案?是的。你可以做的是創造你自己的JSON
版本不會刪除錯誤信息:
import util.parsing.json._
object MyJSON extends Parser {
def parseRaw(input : String) : Either[NoSuccess, JSONType] = {
phrase(root)(new lexical.Scanner(input)) match {
case Success(result, _) => Right(result)
case ns: NoSuccess => Left(ns)
}
}
def parseFull(input: String): Either[NoSuccess, Any] = {
parseRaw(input).right.map(resolveType)
}
def resolveType(input: Any): Any = input match {
case JSONObject(data) => data.transform {
case (k,v) => resolveType(v)
}
case JSONArray(data) => data.map(resolveType)
case x => x
}
}
我只是改變Option
到Either
的結果類型,這樣我就可以返回解析錯誤作爲Left
。 REPL中的一些測試:
scala> MyJSON.parseFull("[1,2,3]")
res11: Either[MyJSON.NoSuccess,Any] = Right(List(1.0, 2.0, 3.0))
scala> MyJSON.parseFull("[1,2,3")
res12: Either[MyJSON.NoSuccess,Any] =
Left([1.7] failure: end of input
[1,2,3
^)
感謝您的答案,但它不適用於我的2.10.0。解析不良數據後,'JSON.lastNoSuccess'爲'null'。 –
確實,我現在可以證實這一點。我做了一個(冗長的)更新,請看看。 –
這是爲我工作。 –