[英]Scala error handling: Try or Either?
Given a method in UserService: update
, what's the best way to handle errors/exceptions here? 给定UserService:
update
的方法,这里处理错误/异常的最佳方法是什么?
def update(...): Try[User]
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 (eg user_id cannot be changed, etc).
大多数这些异常都是业务错误(例如,user_id不能更改等)。 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. 这里的重点是无论抛出什么异常(业务错误,网络异常,DB IO异常等),以同样的方式对待它们并返回
Failure(err)
- 让上层处理它们。
def update(...): Either[Error, User]
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]
. 在函数体中,它捕获所有可能的异常并将它们转换为Error,对于业务错误,只返回
Left[Error]
。
Using Try
seems to be a more natural way to me as I want to handle errors. 使用
Try
对我来说似乎是一种更自然的方式,因为我想处理错误。 Either
is a more generic thing - Either[Error, T]
is just one special case and I think Try
is invented for this special case. Either
是更通用的东西 - Either[Error, T]
只是一个特例,我认为Try
是针对这种特殊情况发明的。 But I also read that we should avoid using exceptions for error handling... 但我也读到我们应该避免使用异常进行错误处理......
So, which solution is better, and why? 那么,哪种解决方案更好,为什么呢?
There's no silver bullet. 没有银弹。
As you noted already, Try
is simply a more specialized version of Either
, where the Left
type is fixed to Throwable
. 正如您已经注意到的,
Try
只是一个更专业的Either
版本,其中Left
类型固定为Throwable
。
Try
might be a good fit if you need to materialize exceptions thrown by external (perhaps java) libraries, as its constructor automatically catches them. 如果你需要实现外部(也许是java)库抛出的异常,那么
Try
可能是一个很好的选择,因为它的构造函数会自动捕获它们。
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. Try
另一个优点是它有map
和flatMap
,所以你可以直接在for-comprehensions中使用它,而使用Either
你必须明确地在right
情况下进行投影。 Anyway, there's plenty of alternative implementations with a "right-bias", and probably the scalaz \\/
type is the most popular one. 无论如何,有很多替代实现具有“右偏”,可能scalaz
\\/
type是最受欢迎的。
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
. 话虽这么说,我通常使用
\\/
或几乎等效的Validation
(都来自scalaz),因为我喜欢能够返回不扩展Throwable
错误。
It also allows for more precise error types, which is a huge win. 它还允许更精确的错误类型,这是一个巨大的胜利。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.