play-json icon indicating copy to clipboard operation
play-json copied to clipboard

Reads.nullable behaves weirdly

Open gmethvin opened this issue 7 years ago • 0 comments

(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?

gmethvin avatar Dec 12 '16 22:12 gmethvin