Scala 错误处理 : Try or Either?

标签 scala error-handling

给定 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的另一个优势是它有mapflatMap ,所以你可以直接在 for-comprehensions 中使用它,而使用 Either您必须在 right 上明确投影案件。
无论如何,有很多具有“右偏”的替代实现,可能还有 scalaz \/类型是最受欢迎的一种。

话虽如此,我通常使用 \/或几乎等效的 Validation (均来自 scalaz),因为我喜欢能够返回不扩展的错误 Throwable .

它还允许更精确的错误类型,这是一个巨大的胜利。

关于Scala 错误处理 : Try or Either?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27171213/

相关文章:

sql-server - SQL Server存储过程错误处理

scala - 实现 "live"流以驱动 Akka 2.4 持久性查询

android - 无法在设备上运行应用

matlab - 不存在的列的 Octave 错误

.net - Scala 闭包在 Scala.NET 中是如何实现的?

php - 如何查看 '@' 抑制的错误?

asp.net - ASP.NET网站自定义404错误被服务器错误阻止

scala - LazyList和Scala中的Stream有什么区别?

algorithm - 在列表上迭代时在 Scala 中跳出循环

带管道的 Scala 进程