Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala error handling: Try or Either?

Given a method in UserService: update, what's the best way to handle errors/exceptions here?

Option 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 (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.

Option 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].

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?

like image 865
x1a0 Avatar asked Nov 27 '14 12:11

x1a0


People also ask

What kind of error handling does Scala have?

Exception handling is the mechanism to respond to the occurrence of an exception. Exceptions can be checked or unchecked. Scala only allows unchecked exceptions, though. This means that, at compile-time, we won't be able to know if a method is throwing an exception we are not handling.

What is try in Scala?

The Try type represents a computation that may either result in an exception, or return a successfully computed value. It's similar to, but semantically different from the scala. util. Either type. Instances of Try[T] , are either an instance of scala.

What is either in Scala?

In Scala Either, functions exactly similar to an Option. The only dissimilarity is that with Either it is practicable to return a string which can explicate the instructions about the error that appeared.


Video Answer


1 Answers

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 might be a good fit if you need to materialize exceptions thrown by external (perhaps java) libraries, as its constructor automatically catches them.

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.

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.

like image 95
Gabriele Petronella Avatar answered Sep 21 '22 17:09

Gabriele Petronella