UserServiceImpl.updateUser
Here’s the code for UserServiceImpl.updateUser:
def updateUser(username: String, info: UserInfo): Future[Option[UserInfo]] = {
{
for {
retrieved <- repo.retrieveOne[User](Username(username))
modified = retrieved.modify(info.mapUser)
updated <- repo.update(modified)
} yield {
Some(UserInfo(updated.get))
}
} recover {
case e: DuplicateKeyValException[_, _] => handleDuplicateKeyVal(e, info)
case e: NoSuchElementException => None
}
}
This method shows a variation on repo.retrieve:
repo.retrieveOne. retrieveOne opens up the Option for you,
throwing a NoSuchElementException if the Option is empty. We
handle the NoSuchElementException in the recover clause, returning
None if the User was not found. Akka HTTP will handle the None
by returning a 404 Not Found, which is exactly what we want.
The retrieved in the for comprehension is a PState[User]. Calling
retrieved.modify produces another PState[User] that reflects the
changes produced by the function passed to modify. In this case, we
call UserInfo.mapUser, which updates a User according to the
information in the UserInfo. The resulting PState is stored in a
local value named modified.
We then pass modified on to repo.update. This method persists
the changes, but like repo.create, it might generate a
DuplicateKeyValException if we try to update the user to have a
conflicting username or email. Once again, we handle this problem in
the recover clause, converting the longevity exception into a Simple
Blogging service exception.