2013-05-25 6 views
16

Przykłady tego rodzaju komunikatów produkowanych przez Play JSON API:coraz lepiej komunikaty błędów z gry JSON API

scala> import play.api.libs.json._ 
import play.api.libs.json._ 

scala> Json.obj("k" -> Json.obj("m" -> 7)) 
res0: play.api.libs.json.JsObject = {"k":{"m":7}} 

scala> (res0 \ "p").as[String] 
play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(validate.error.expected.jsstring,WrappedArray()))))) 
    at play.api.libs.json.JsValue$$anonfun$2.apply(JsValue.scala:67) 
    at play.api.libs.json.JsValue$$anonfun$2.apply(JsValue.scala:67) 
    at play.api.libs.json.JsResult$class.fold(JsResult.scala:69) 
    at play.api.libs.json.JsError.fold(JsResult.scala:10) 
    at play.api.libs.json.JsValue$class.as(JsValue.scala:65) 
    at play.api.libs.json.JsUndefined.as(JsValue.scala:98) 
    at .<init>(<console>:12) 
    at .<clinit>(<console>) 
    at .<init>(<console>:7) 
    // gazillion lines more 

scala> (res0 \ "k" \ "m").as[String] 
play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(validate.error.expected.jsstring,WrappedArray()))))) 
    at play.api.libs.json.JsValue$$anonfun$2.apply(JsValue.scala:67) 
    at play.api.libs.json.JsValue$$anonfun$2.apply(JsValue.scala:67) 
    at play.api.libs.json.JsResult$class.fold(JsResult.scala:69) 
    at play.api.libs.json.JsError.fold(JsResult.scala:10) 
    at play.api.libs.json.JsValue$class.as(JsValue.scala:65) 
    at play.api.libs.json.JsNumber.as(JsValue.scala:108) 
    at .<init>(<console>:12) 
    at .<clinit>(<console>) 
    at .<init>(<console>:7) 
    // gazillion lines more 

Czy istnieje sposób, aby uzyskać lepsze komunikaty o błędach z tym API? Na przykład, komunikaty o błędach dla dwóch powyższych przypadkach mogłaby wyglądać No value found at JsPath \ "p", Value found at JsPath \ "k" \ "m" cannot be read as type String itp

Odpowiedz

10

tak wykorzystujące JsValue.as[T] nie jest mocny w tym przypadku:

res0 \ "p" powraca JsUndefined który następnie zastosowane do niejawny Reads[String] i to mówi „hej nie jest to String” ... to prawda, ale nie to, czego można się spodziewać;)

lepszy sposób IMHO wykorzystuje Reads na JsPath bezpośrednio:

scala> ((__ \ "p").read[String]).reads(res0) 
res7: play.api.libs.json.JsResult[String] = JsError(List((/p,List(ValidationError(validate.error.missing-path,WrappedArray()))))) 

scala> ((__ \ "k" \ "m").read[String]).reads(res0) 
res8: play.api.libs.json.JsResult[String] = JsError(List((/k/m,List(ValidationError(validate.error.expected.jsstring,WrappedArray()))))) 

Tutaj masz lepszy komunikat o brakującej ścieżce. To nawet powiadamia brakującą ścieżkę w pierwszym parametrze w JsError.

W przypadku wiadomości jako ładnych ciągów można użyć lokalnej wiadomości do odwzorowania klucza. BTW, te komunikaty o błędach Jsona nie są dość wystandaryzowane w odniesieniu do innych komunikatów o błędach w grze, takich jak formularze. Myślę, że poprawimy to w przyszłej wersji Play.

Wreszcie, kiedy chcesz wysłać błędy sprawdzania poprawności JSON do klienta, istnieje funkcja pomocnika w JsError korzystać z JsResult.recoverTotal

scala> ((__ \ "k" \ "m").read[String]).reads(res0).recoverTotal(e => JsError.toFlatJson(e)) 
res11: java.io.Serializable = {"obj.k.m":[{"msg":"validate.error.expected.jsstring","args":[]}]} 

To tylko surowe wersja tego rodzaju funkcji. Jeśli potrzebujesz innego formatu, radzę przyjrzeć się implementacji FlatJson i napisać własną.

Miłej zabawy;)

+2

Dlaczego nie jest domyślny sposób działania domyślnych metod dostępu w 'JsValue'? Błąd zgłaszania spraw. :( – missingfaktor

+0

@mandubian - Mam typ Long w jednej z właściwości klasy scala case, ale kiedy konwertuję json na seq tej klasy, to daje mi "erro.expected.long" –

+0

Jeśli nawet powiedział, w której linii błąd zdarza się, że nie byłoby * tak * strasznie. – JulienD

Powiązane problemy