【发布时间】:2018-09-25 10:59:03
【问题描述】:
我有一个从数据库中获取一些数据的服务类(对于上下文,我使用的是 Play!Framework)。这是一个示例方法:
def getAccessToken(id: BSONObjectID): Future[Option[String]] = {
userDAO.find(id).map {
case Some(user) =>
user.settings flatMap (_.accessToken)
case _ => None
}
}
我正在尝试改进这件事的错误处理(Scala 的新功能),因为有几件事可能会出错:
- 可能找不到用户
- 可能会找到用户,但可能未设置
accessToken(accessToken是Option[String])
就目前而言,我无法区分两者。我解决这个问题的自然倾向是使用来自 Scalaz 的\/ 并将返回类型设置为Future[ErrorType \/ String],这似乎是一种合理的方法。在我的控制器方法中,我可以通过提升到包装器 monad 来理解一堆不同的服务方法。
但我有以下问题:
我的
ErrorType应该扩展Exception,还是应该只使用密封特征样式并从中扩展。我听说在 Scala 中使用异常不是一个好习惯,所以我不确定正确的方法是什么。-
如何处理日志而不用过多的日志语句污染控制器类?如果一个控制器类调用了一堆这样的服务方法,控制器将不得不在 for comprehension 中处理几个不同的
ErrorTypes。假设我使用?|将所有单子提升到包装单子,我想避免这种情况:accessToken <- service.getAccessToken(id) ?| { error => error match { case Error1 => logger.error( "Unable to find access token for user: " + id .toString()) InternalServerError( ApiResponse("internal_server_error", "Unable to get token.")) case Error2 => ... }
谢谢!
【问题讨论】:
标签: scala playframework-2.0 scalaz