In a REST API implemented with Play Framework (2.4), I'm using Action(parse.json) to parse JSON from incoming POST request body.
With my current code (see below),
Posting valid JSON with missing fields (e.g. {"foo": ""}) produces
400 with the response body {"error":"Missing input fields"}. This is fine and expected. 👍
Posting completely invalid JSON (such as {,,,} or {\00}) produces
400 with a long HTML response body. 👎 This comes from somewhere within
parse.json.
In the latter case, how to get rid of the HTML response body? I'd like the response body to either contain a short JSON error message (such as {"error":"Invalid JSON input"}), or nothing at all. Does Play have a config option for this, or would I need to create a custom Action? What is the simplest way?
Controller method:
def test = Action(parse.json) { request =>
  request.body.validate[Input].map(i => {
    Ok(i.foo)
  }).getOrElse(BadRequest(errorJson("Missing input fields")))
}
Other stuff used above:
case class Input(foo: String, bar: String)
object Input {
  implicit val reads = Json.reads[Input]
}
case class ErrorJson(error: String)
object ErrorJson {
  implicit val writes = Json.writes[ErrorJson]
}
private def errorJson(message: String) = Json.toJson(ErrorJson(message))
The long html is produced by the default HttpErrorHandler. You can provide your own by following this guide. Quoting the example code:
class ErrorHandler extends HttpErrorHandler { def onClientError(request: RequestHeader, statusCode: Int, message: String) = { Future.successful( Status(statusCode)("A client error occurred: " + message) ) } def onServerError(request: RequestHeader, exception: Throwable) = { Future.successful( InternalServerError("A server error occurred: " + exception.getMessage) ) } }
Note: if you manage your dependencies without Guice, you will have to provide your custom HttpErrorHandler in the ApplicationLoader
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With