Handling JSON parse errors of third party services in play applications

441 Views Asked by At

I'm wondering what's an acceptable approach to parsing JSON from third-party services considering deserialization errors.

For example, this service method:

  def signInWithEmailAndPassword(email: String, password: String): Future[ApiResponse[SignInResponse]] =
    request("/signin").post(Json.obj("email" -> email, "password" -> password))
      .map(_.json.as[ApiResponse[SignInResponse]])

Will throw a server exception if json.as fails which play will catch in the default error handler.

Is that an OK structuring of the client? Seems like a JSON parse error is not really recoverable anyway, so uses the generic error handler is appropriate?

2

There are 2 best solutions below

1
On BEST ANSWER

Assuming ApiResponse is going to hold any client errors (wrong password, etc) and the Future is going to hold server errors (couldn't establish connection, 500 from remote service, etc), then yes it's appropriate for the exception in the Future to bubble up to the error handler and return a 500 to your caller (also assuming there are no resources you need to clean up before returning).

0
On

Here is some sample to help you get started. This is a method that you normally write in your Play framework controller.

def dispatchPowerPlant(id: Int) = Action.async(parse.tolerantJson) { request =>
    request.body.validate[DispatchCommand].fold(
      errors => {
        Future.successful{
          BadRequest(
            Json.obj("status" -> "error", "message" -> JsError.toJson(errors))
          )
        }
      },
      dispatchCommand => {
        actorFor(id) flatMap {
          case None =>
            Future.successful {
              NotFound(s"HTTP 404 :: PowerPlant with ID $id not found")
            }
          case Some(actorRef) =>
            sendCommand(actorRef, id, dispatchCommand)
        }
      }
    )
  }

So what it does is to check the validity of the JSON payload and send the response accordingly! Hope this helps!

You could probably have a similar setup to validate the JSON and return the response accordingly.