Scala · Concurrency, Testing & Ecosystem

Error Handling with Try

Try wraps code that might throw an exception and turns the result into a value you can work with.

Advanced 5 min Lesson 21 of 25Examples use Scala 3 (3.3 LTS or newer) with sbt or scala-cli.
Before you start:Option and Either
0/25 in Scala
On this page · 5 min · Advanced

In simple words#

Try is a sealed envelope from an exam: open it and you find either a result (Success) or a note explaining what went wrong (Failure). Either way, you get an envelope — nothing explodes.

Try[A]
Success(value) or Failure(exception).
recover
Replace a Failure with a fallback.
toEither
Convert to Either[Throwable, A].

Learning objectives#

  • Wrap risky code with Try
  • Handle Success and Failure
  • Chain Try operations
  • Choose Try vs Option vs Either

Explanation#

Try("42".toInt) gives Success(42); Try("abc".toInt) gives Failure(NumberFormatException).

map, flatMap, getOrElse, recover and match work like on Option.

Use Try at boundaries with exception-throwing code (Java libraries, parsing, I/O).

Inside your own domain, prefer Either with meaningful error types; use Option when “missing” is not an error.

Code example: Parsing a config safely#

ScalaParsing a config safely Illustrative
import scala.util.{Try, Success, Failure}


def parsePort(value: String): Try[Int] =
  Try(value.trim.toInt).flatMap { p =>
    if p >= 1 && p <= 65535 then Success(p)
    else Failure(IllegalArgumentException(s"Port out of range: $p"))
  }


List("8080", "abc", "70000").foreach { v =>
  parsePort(v) match
    case Success(port) => println(s"Using port $port")
    case Failure(e)    => println(s"Invalid '$v': ${e.getMessage}")
}


val port = parsePort("oops").recover { case _: NumberFormatException => 3000 }.get
println(s"Fallback port: $port")
println(parsePort("443").toEither)
Expected output
Using port 8080
Invalid 'abc': For input string: "abc"
Invalid '70000': Port out of range: 70000
Fallback port: 3000
Right(443)

This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.

Step-by-step explanation#

  1. Try catches NumberFormatException.
  2. flatMap adds a range check.
  3. match handles Success and Failure.
  4. recover supplies a default; toEither converts.

Real-world use case#

Reading environment variables, parsing files and calling Java APIs are wrapped in Try at the edges of a service.

Common mistakes#

Calling .get on Failure

It rethrows the exception. Use getOrElse, recover or match.

Using Try for business errors

Domain errors are clearer as Either[MyError, A].

Best practices#

  • Try at boundaries
  • Either for domain errors
  • Option for absence
  • Never swallow failures silently

Remember this#

Try = Success | Failure.

Wrap throwing code at the edge.

Try for exceptions, Either for domain errors, Option for missing.

Practice exercise#

Your task: Safely divide two Ints with Try, returning 0 on failure.

Show solution
Scala Illustrative
def safeDiv(a: Int, b: Int): Int = Try(a / b).getOrElse(0)

Mini quiz#

Error Handling with Try quizMultiple choice Question 1 of 1

What does Try("abc".toInt) return?

Score so far: 0/0

Want more? Practise all Scala MCQs · Scala interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.