Reputation: 2327
Currently have the following implicit Reads val:
implicit val abridgedProductReads: Reads[Product] =
(
(JsPath \ "ean" ).read[Long] and
(JsPath \ "name" ).read[String](minLength[String](5)) and
(JsPath \ "description").read[Option[String]]
)(abridgedProductApply _)
and the following for writing validation errors:
implicit val JsPathWrites = Writes[JsPath] (path => JsString(path.toString))
implicit val ValidationErrorWrites = Writes[ValidationError](error => JsString(error.message))
implicit val jsonValidateErrorWrites =
(
(JsPath \ "path" ).write[JsPath] and
(JsPath \ "errors").write[Seq[ValidationError]]
tupled
)
When I submit a name which is too short, I get a Json message like:
[{"path":"/name","errors":"error.minLength"}]
Which I am currently using the following CoffeeScript:
extractError = (message) ->
errorObj = $.parseJSON(message)
error = "Unextracted"
try error = errorObj[0].path + " has error: " + errorObj[0].errors
catch e then error = message
error
to present to user as:
/name has error: error.minLength
But I'd like to customize this to make it friendlier (e.g. "Name must be at least five characters") without making any assumption on the client side that this will be the only error presented. In the future, I might add more fields and more validation rules.
Ideally, I'd like Play to be serving user friendly errors, rather than write the CoffeeScript to try to interpret the errors it is receiving.
What would be the best way to do this?
Upvotes: 0
Views: 520
Reputation: 13985
Looks like you want to define your custom validation constraint.
def customMinLength[M]( m: Int )
(
implicit reads: Reads[M],
p: M => scala.collection.TraversableLike[_, M]
) =
filterNot[M]( ValidationError(
"Well.... you see... I want to tell you in a very humanized way that your string is shorter than what it should be. For your information its length should be at least " + m.toString,
m
) )( _.size < m )
implicit val abridgedProductReads: Reads[Product] = (
(JsPath \ "ean" ).read[Long] and
(JsPath \ "name" ).read[String](customMinLength[String](5)) and
(JsPath \ "description").read[Option[String]]
)(abridgedProductApply _)
Upvotes: 1