I'm trying to get Play to validate + convert a json request body into a case class. If the validation fails, I'd like to send back a list of human readable error messages.
My case class is a simple login request:
case class LoginReq(user: String, password: String)
I'd like to send errors in a simple format, such as:
{"errors": ["User was not provided", "Password was not provided"]}
This is what I've implemented so far:
@Singleton
class LoginController @Inject()(cc: ControllerComponents) extends AbstractController(cc) {
case class LoginReq(user: String, password: String)
implicit val reqFormat = Json.format[LoginReq]
def index() = Action(parse.json) { req =>
val loginReq = req.body.validate[LoginReq]
loginReq match {
case JsSuccess(r: LoginReq, path: JsPath) => Ok(Json.toJson(r))
case e: JsError =>
UnprocessableEntity(JsError.toJson(e))
}
}
}
The problem is, the line :
case e: JsError => UnprocessableEntity(JsError.toJson(e))
produces the errors in this format:
{
"obj.user": [
{
"msg": [
"error.path.missing"
],
"args": []
}
],
"obj.password": [
{
"msg": [
"error.path.missing"
],
"args": []
}
]
}
rather than:
{"errors": ["User was not provided", "Password was not provided"]}
Is there a built in / easy way that i'm missing, to convert the errors into a more human readable way? At least convert error.path.missing into something like was not provided? Or do I need to write this myself?