The Either type is a cool way to handle errors in Scala code. From the docs:

Represents a value of one of two possible types (a disjoint union.) Instances of Either are either an instance of Left or Right.

Convention dictates that Left is used for failure and Right is used for success.

http://www.scala-lang.org/api/2.9.2/scala/Either.html

To put it in practical terms, and Either is (yet another Scala) way to wrap potentially unsafe values. For example, let’s say we have a function that makes an HTTP call, and can therefore travel down a happy path where the call succeeds, or a sad path where the HTTP call fails. This function making the HTTP call can return an Either, and callers of the function would be able to unwrap the value in a safe and predicable way.

Let’s refactor our Failing Gracefully Scala post which used the Try Success Failure paradigm to use Either.

def fetch(url: String): Either[Throwable, String] = {
  try {
    Right(scala.io.Source.fromURL(url).mkString)
  } catch {
    case e: Throwable => Left(e)
  }
}
val goodURL = "https://lombardo-chcg.github.io/"
val badURL = "https://lombardo-chcg.github.io/INVALID_ENDPOINT"

fetch(goodURL)
// Right(a bunch of html as a string...)

fetch(badURL)

// Left(java.io.FileNotFoundException: https://lombardo-chcg.github.io/INVALID_ENDPOINT)

This is easy to pattern match against for graceful error handling:

fetch(badURL) match {
  case Right(someData) => println("SUCCESS")
  case Left(someException) => println("whoops...", someException.getMessage)
}

// (whoops...,https://lombardo-chcg.github.io/INVALID_ENDPOINT)

It would be easy to have services to handle each case. The Left side could even be a retry policy.

Since we’re in Scala land, here’s a cool functional-style method we get for free on Either types called fold. It does the typical fold behavior of returning a single value, but in this case we pass the method a function to handle the left case and the right case, and it does the rest.

def handleLeft(exception: Throwable) = println("whoops...", exception.getMessage)
def handleRight(data: String) = println(data)

fetch(badURL).fold(handleLeft, handleRight)
fetch(goodURL).fold(handleLeft, handleRight)