Search code examples
jsonscalaplayframeworkplay-json

why is JsError converted to JsSuccess of default?


I am using Play-Json 2.6.3 WithDefaultValues as below

implicit def jsonFormatFoo = Json.using[Json.WithDefaultValues].format[Foo]

 implicit def jsonFormatBar = Json.using[Json.WithDefaultValues].format[Bar]

But it gives unexpected behavior for :

case class Bar(name:String)
case class Foo(bars: List[Bars] = List.empty)

Now if I do

val result = Json.parse("""{"bars":[{"name":null}]}""").validate[Foo]

println(result)

I get JsSuccess(Foo(List()),). I was expecting JsError(List((/bars(0)/name,List(JsonValidationError(List(error.expected.jsstring),WrappedArray()))))) which only comes once I remove the default List.empty.

If I have a default, why is JsError converted to JsSuccess of the default value ? Its bit unintuitive. How do I resolve it ?


Solution

  • There is some change starting version Play-JSON 2.6.8. If you switch to it or to higher version, then it should start complain on null value for Bar:

    libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.8"
    
    @ import play.api.libs.json._
    import play.api.libs.json._
    
    @  case class Bar(name:String)
    defined class Bar
    
    @  case class Foo(bars: List[Bar] = List.empty)
    defined class Foo
    
    @ implicit def jsonFormatBar = Json.using[Json.WithDefaultValues].format[Bar]
    defined function jsonFormatBar
    
    @ implicit def jsonFormatFoo = Json.using[Json.WithDefaultValues].format[Foo]
    defined function jsonFormatFoo
    
    @ Json.parse("""{"bars":[{"name":null}]}""").validate[Foo]
    res6: JsResult[Foo] = JsError(List((JsPath(List(KeyPathNode("bars"), IdxPathNode(0), KeyPathNode("name"))), List(JsonValidationError(List("error.expected.jsstring"), WrappedArray())))))