Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Future[Either[AppError, Option[User]]] in Scala

As mentioned in the title, does it make sense to use such data structure? Let me explain one by one:

  • Future - to represent async computation
  • Either - to communicate known errors
  • Option - to communicate that the value may not be present

I am a little bit scared when looking at this. Is it a good practice to use such type combination?

like image 711
user3763116 Avatar asked Oct 27 '16 11:10

user3763116


1 Answers

Let's have a look at the solution space:

Success(Right(Some(user))) => Everythig OK, got an user
Success(Right(None)) => Everything OK, no user
Success(Left(AppError)) => Something went wrong at app level
Failure(Exception) => Something went wrong

This looks very expressive, but things get ugly fast when you try to compose such nested structure with other calls (see Converting blocking code to using scala futures) for an example of composingFuture[Option[T]])

So following the principle of the least power, we ask ourselves: Are there less complex alternatives that preserve the semantics? One could argue that Future[User] could be sufficient if we make use of the full potential of exception (and exception hierarchies).

Let's check:

Everythig OK, got an user => Success(user)
Everything OK, no user => Failure(UserNotFoundException)  (Application level exception)
Something went wrong at app level => Failure(AppException) (Application level exception)
Something went wrong => Failure(Exception) (System-level exception)

The only limitation of this approach is that the users of the API will need to be aware of the Exceptions, which is not self-documented in the interface. The upper-hand is that having an API based on Futures will allow expressive monadic compositions with other Future-based APIs.

like image 64
maasg Avatar answered Oct 21 '22 01:10

maasg