play-json
play-json copied to clipboard
Reads.nullable behaves weirdly
(Moved from playframework/playframework#5863)
Actual Behavior
scala> import play.api.libs.json._
import play.api.libs.json._
scala> (__ \ "foo").readNullable[String]
res0: play.api.libs.json.Reads[Option[String]] = play.api.libs.json.Reads$$anon$8@4a733e24
scala> res0.reads(Json.obj())
res1: play.api.libs.json.JsResult[Option[String]] = JsSuccess(None,)
scala> res0.reads(JsString("hello"))
res2: play.api.libs.json.JsResult[Option[String]] = JsSuccess(None,)
Expected Behavior
res2
should be a JsError
.
We are trying to apply a Reads
that tries to read a foo
field, however our JSON value is not an object but a string. What does “reading a field” mean in the case of a string value?
Note that the case of res1
is perfectly fine: we try to read a foo
field in an object that does not have such a field, so we successfully read no field.
Proposed Fix
Reads.nullable
should successfully read no field (ie. return JsSuccess(None)
) only if the input JSON is an object and the last path node is a KeyPathNode
, or if the input JSON is an array and the last path node is a IdxPathNode
.
What should we do in case of RecursiveSearch
?