Scala错误处理:尝试还是选择? [英] Scala error handling: Try or Either?
问题描述
给出UserService中的方法: update
,在这里处理错误/异常的最佳方法是什么?
Given a method in UserService: update
, what's the best way to handle errors/exceptions here?
def update(...): Try[User]
这样,我需要定义我的自定义异常,并在需要时将它们扔到函数主体中。这些异常大多数是业务错误(例如,无法更改user_id等)。这里的重点是无论抛出什么异常(业务错误,网络异常,DB IO异常等),以相同的方式对待它们,只是返回 Failure(err)
-让上层处理它们。
In this way, I need to define my custom exceptions and throw them in the function body when needed. Most of these exceptions are business errors (e.g. user_id cannot be changed, etc). The point here is no matter what exception(s) are thrown (business error, network exception, DB IO exception, etc), treat them the same way and just return a Failure(err)
- let the upper layer handle them.
def update(...): Either[Error, User]
这是例外-高速公路。在函数主体中,它捕获所有可能的异常并将其转换为Error,对于业务错误,只需返回 Left [Error]
。
This is the exception-free way. In the function body it catches all possible exceptions and turns them into Error, and for business errors just return Left[Error]
.
使用 Try
对我来说似乎是一种更自然的方法,因为我想处理错误。 任何一个
是一个更通用的东西-任何一个[Error,T]
只是一个特例,我认为<$ c为此特殊情况发明了$ c> Try 。但是我也读到我们应该避免使用异常进行错误处理...
Using Try
seems to be a more natural way to me as I want to handle errors. Either
is a more generic thing - Either[Error, T]
is just one special case and I think Try
is invented for this special case. But I also read that we should avoid using exceptions for error handling...
因此,哪种解决方案更好,为什么?
So, which solution is better, and why?
推荐答案
没有灵丹妙药。
正如您已经提到的,尝试
只是 Either
的更专业版本,其中 Left
类型固定为 Throwable
。
As you noted already, Try
is simply a more specialized version of Either
, where the Left
type is fixed to Throwable
.
尝试
可能是一个不错的选择实例化由外部(也许是Java)库抛出的异常,因为其构造函数会自动捕获它们。
Try
might be a good fit if you need to materialize exceptions thrown by external (perhaps java) libraries, as its constructor automatically catches them.
Try
的另一个优点是它具有 map
和 flatMap
,因此您可以直接将其用于理解,而使用任何一个
,您都必须在 right
情况下显式投影。
无论如何,有很多带有右偏的替代实现,可能最流行的是scalaz \ /
类型。
Another advantage of Try
is that it has map
and flatMap
, so you can use it directly in for-comprehensions, whereas with Either
you would have to explicitly project on the right
case.
Anyway, there's plenty of alternative implementations with a "right-bias", and probably the scalaz \/
type is the most popular one.
也就是说,我通常使用 \ /
或几乎等效的 Validation
(均来自scalaz),因为我希望能够返回不会扩展 Throwable
的错误。
That being said, I typically use \/
or the almost equivalent Validation
(both from scalaz), as I like having the ability of returning errors that do not extend Throwable
.
它还允许更精确的错误类型,这是一个巨大的胜利。
It also allows for more precise error types, which is a huge win.
这篇关于Scala错误处理:尝试还是选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!