Scala Lesson 35 – Either and Try | Dataplexa

Either & Try

In this lesson, you will learn how to handle errors safely and clearly in Scala using Either and Try. These constructs are widely used in functional programming to avoid unexpected crashes and to make error handling explicit.

Instead of throwing exceptions or returning null values, Scala encourages using types that clearly describe success and failure.


Why Error Handling Matters

Traditional error handling using exceptions can lead to:

  • Hidden control flow
  • Unexpected runtime crashes
  • Difficult debugging

Scala’s Either and Try solve these problems by making errors part of the program’s type system.


Understanding Either

Either[A, B] represents a value that can be one of two possibilities:

  • Left[A] – usually represents an error
  • Right[B] – usually represents a success

By convention, Right is used for successful results.

def divide(a: Int, b: Int): Either[String, Int] =
  if (b == 0) Left("Division by zero")
  else Right(a / b)

Using Either Safely

You can safely transform a successful value using map.

val result = divide(10, 2).map(_ * 2)
println(result)

If the value is Left, the transformation is skipped.


Chaining Operations with flatMap

When a function itself returns an Either, use flatMap to avoid nested results.

def reciprocal(x: Int): Either[String, Double] =
  if (x == 0) Left("Cannot take reciprocal of zero")
  else Right(1.0 / x)

val result =
  divide(20, 2).flatMap(reciprocal)

println(result)

For-Comprehensions with Either

For-comprehensions make chained error handling easy to read.

val result = for {
  a <- divide(20, 2)
  b <- reciprocal(a)
} yield b

println(result)

If any step fails, the entire computation returns a Left.


Understanding Try

Try is used to capture exceptions that may occur during execution.

  • Success(value) – represents successful computation
  • Failure(exception) – represents an exception
import scala.util.Try

val result = Try(10 / 2)
println(result)

Transforming Try with map

Just like Either, Try supports map and flatMap.

val transformed = Try(10 / 2).map(_ * 3)
println(transformed)

If an exception occurs, the result becomes a Failure.


Recovering from Errors

You can recover from failures using recover or recoverWith.

val safeResult = Try(10 / 0).recover {
  case _: ArithmeticException => 0
}

println(safeResult)

Either vs Try

Both are useful, but they serve different purposes:

  • Either – best for predictable, domain-level errors
  • Try – best for catching unexpected exceptions

In production systems, Either is often preferred for business logic, while Try is used near risky operations.


📝 Practice Exercises


Exercise 1

Write a function that returns an Either when dividing two numbers.

Exercise 2

Use a for-comprehension to chain two Either operations.

Exercise 3

Wrap a risky operation using Try and recover from failure.


✅ Practice Answers


Answer 1

def safeDivide(a: Int, b: Int): Either[String, Int] =
  if (b == 0) Left("Cannot divide by zero")
  else Right(a / b)

Answer 2

val result = for {
  x <- safeDivide(20, 2)
  y <- safeDivide(x, 2)
} yield y

Answer 3

val result = Try("abc".toInt).recover {
  case _: NumberFormatException => 0
}

What’s Next?

In the next lesson, you will learn about For-Comprehensions and how they simplify complex transformations across collections, Option, Either, and Try.