简体   繁体   English

Scala错误处理:尝试还是要么?

[英]Scala error handling: Try or Either?

Given a method in UserService: update , what's the best way to handle errors/exceptions here? 给定UserService: update的方法,这里处理错误/异常的最佳方法是什么?

Option A: 选项A:

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) - 让上层处理它们。

Option B: 选项B:

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另一个优点是它有mapflatMap ,所以你可以直接在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM