给定 UserService 中的一个方法:update
,这里处理错误/异常的最佳方法是什么?
选项A:
def update(...): Try[User]
这样,我需要定义我的自定义异常(exception) 并在需要时将它们扔到函数体中。这些异常中的大多数是业务错误(例如 user_id 无法更改等)。这里的重点是无论抛出什么异常(业务错误、网络异常、DB IO 异常等),都以同样的方式对待它们,只返回一个
Failure(err)
- 让上层处理它们。选项 B:
def update(...): Either[Error, User]
这是无异常的方式。在函数体中,它捕获所有可能的异常并将它们转换为 Error,对于业务错误只需返回
Left[Error]
.使用
Try
对我来说似乎是一种更自然的方式,因为我想处理错误。 Either
是一个更通用的东西 - Either[Error, T]
只是一种特例,我认为 Try
是为这种特殊情况发明的。但我也读到我们应该避免使用异常进行错误处理......那么,哪种解决方案更好,为什么?
最佳答案
没有银弹。
正如您已经注意到的,Try
只是 Either
的更专业版本,其中Left
类型固定为 Throwable
.Try
如果您需要实现外部(可能是 java)库抛出的异常,可能是一个很好的选择,因为它的构造函数会自动捕获它们。Try
的另一个优势是它有map
和 flatMap
,所以你可以直接在 for-comprehensions 中使用它,而使用 Either
您必须在 right
上明确投影案件。
无论如何,有很多具有“右偏”的替代实现,可能还有 scalaz \/
类型是最受欢迎的一种。
话虽如此,我通常使用 \/
或几乎等效的 Validation
(均来自 scalaz),因为我喜欢能够返回不扩展的错误 Throwable
.
它还允许更精确的错误类型,这是一个巨大的胜利。
关于Scala 错误处理 : Try or Either?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27171213/