How to improve readability of error message returned from JsError.toFlatJson or JsError.toJson in Play Framework 2.x?

I have a JSON REST API server built using the Play v2.3 platform with scala, and I have a controller action, for example this:

def register = Action.async(BodyParsers.parse.json) { implicit request => request.body.validate[Register].fold( errors => Future.successful(BadRequest(JsError.toFlatJson(errors))), register => { // do something here if no error... } ) } 

For simplicity, I handle the validation error with JsError.toFlatJson (note: JsError.toFlatJson is deprecated in the new Play, replacement is JsError.toJson ).

The problem is that the json result has a cryptic message like:

{"obj.person.email":[{"msg":"error.email","args":[]}]}

Above json indicates that the person's email message is invalid.

Is there a way to convert the result of a json error into a more readable message?

I do not want client applications to perform obj.person.email or error.email mapping / conversion. I prefer the server to do this before json returns to client applications.

+6
source share
1 answer

Part of your problem can be resolved by defining custom error messages in the Reads combinator with orElse :

 case Point(x: Int, y: Int) object Point { implicit val pointReads: Reads[Point] = ( (__ \ "x").read[Int].orElse(Reads(_ => JsError("Could not parse given x value."))) (__ \ "y").read[Int].orElse(Reads(_ => JsError("Could not parse given y value."))) )(Point.apply _) } 

Given some invalid JSON for this class, you will get custom error messages for checking:

 scala> val incorrectJson = Json.parse("""{"y": 1}""") incorrectJson: play.api.libs.json.JsValue = {"y":1} scala> val validationResult = incorrectJson.validate[Point] validationResult: play.api.libs.json.JsResult[playground.Point] = JsError(List((/x,List(ValidationError(List(Could not read the point x value.),WrappedArray()))))) scala> validationResult.fold(error => { println(JsError.toJson(error)) }, a => { a }) {"obj.x":[{"msg":["Could not read the point x value."],"args":[]}]} 

To change the obj.x identifier, you will need to process the returned JsValue yourself, because it is derived from the JsPath implementation.

0
source

Source: https://habr.com/ru/post/984230/


All Articles