dictionary - Scala - Futures and Eithers -
this thread gave me idea how structure code: scala-way handle conditions in for-comprehensions?
the part in question:
// first create json val resultfuture: future[either[failure, jsresult]] = { userres <- userdao.finduser(userid) user <- userres.withfailure(usernotfound).right authres <- userdao.authenticate(user) auth <- authres.withfailure(notauthenticated).right goodres <- gooddao.findgood(goodid) <- goodres.withfailure(goodnotfound).right checkedgood <- checkgood(user, good).right } yield renderjson(map("success" -> true)))
this lines not understand:
user <- userres.withfailure(usernotfound).right authres <- userdao.authenticate(user)
the userres.withfailure(usernotfound).right mapped userdao.authenticate(user). create new either future on right, correct?
how can
val resultfuture: future[either[failure, jsresult]]
be of type. think instead of jsresult there should future. can explain me?
edit: since cmbaxter , arne claassen confirmed this, new question is: how should write code, not ugly, clean , structured?
i believe answer received needlessly mixed either
's mix when future
's capable of communicating failure. main thing missing way option
option's value without explicitly throwing exceptions.
i suggest change failures object following:
object failures { sealed trait failure extends exception // 4 types of possible failures here case object usernotfound extends failure case object notauthenticated extends failure case object goodnotfound extends failure case object noownership extends failure // put other errors here... // converts options futures implicit class opt2future[a](opt: option[a]) { def withfailure(f: failure) = opt match { case none => future.failed(f) case some(x) => future.successful(x) } } }
now can map future[option[a]]
future[a]
, specify failure condition, resulting in comprehension this:
def checkgood(user: user, good: good) = if (checkownership(user, good)) future.successful(good) else future.failed(noownership) val resultfuture: future[jsresult] = { useropt <- userdao.finduser(userid) user <- useropt.withfailure(usernotfound) authopt <- userdao.authenticate(user) auth <- authopt.withfailure(notauthenticated) goodopt <- goodres.withfailure(goodnotfound) checkedgood <- checkgood(user, good) } yield renderjson(map("success" -> true))))
now have future[jsresult]
can map failed scenarios desired output , success scenario jsresult. using in asynchronous framework expects feed future , has own failed future error response mapping (such play!).
Comments
Post a Comment