Skip to content

Instantly share code, notes, and snippets.

@jeffmay
Last active August 29, 2015 14:04
Show Gist options
  • Save jeffmay/ad071f9dccfa959504e7 to your computer and use it in GitHub Desktop.
Save jeffmay/ad071f9dccfa959504e7 to your computer and use it in GitHub Desktop.
Play Json parser helpers
trait HelperThing {
def badRequestFormatMessage: String = ???
implicit class JsResultOps[T : ClassTag](result: JsResult[T]) {
/**
* Folds either JsError or JsSuccess into a result.
*
* @note the error case is always handled synchronously, if you want to recover from an error
* asynchronously, you can use:
*
* {{{
* result map transform recoverTotal { error => ???: Future[Result] }
* }}}
*
* @param onError handles the JsError case by returning a [[Result]] immediately and synchronously
* @param transform transforms the successful parsing of [[T]] into a [[FinalResult]]
* @tparam FinalResult the return type required to fulfill the action that can be build from the [[Result]]
*/
def foldToResult[FinalResult](
onError: JsError => Result = error => badRequestJson(error)
)(
transform: T => FinalResult
)(implicit buildsFromResult: CanBuildFromResult[FinalResult]): FinalResult = {
result map transform recoverTotal (onError andThen buildsFromResult)
}
def badRequestJson(
error: JsError,
details: String = s"Could not parse an instance of ${classTag[T]} from the request."
): Result = {
val pathErrors = JsError.toFlatJson(error)
val errorMessage = RestErrorMessage.badJson(details)
val errorMessageJson = Json.toJson(errorMessage).as[JsObject]
val finalJson = errorMessageJson ++ pathErrors
BadRequest(finalJson)
}
}
}
@jeffmay
Copy link
Author

jeffmay commented Jul 29, 2014

Example usage:

request.body.validate[AssociateUserRequest].foldToResult() {
      msg =>
        val futureResult = eligibilityService.associateUser(msg.userId, PartnerName(partner), msg.affiliation, msg.partnerUserKey)
        futureResult map {
          case Some(attrs) => Ok(Json.toJson(attrs))
          case None => Ok(Json.toJson(NoPartnerAttributesFound(msg.userId, PartnerName(partner), msg.partnerUserKey)))
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment