While building an application, it is common that something might go wrong. What if there is an attempt to divide a number by 0 or fetching the data from the database which does not exist, or reading a file which can’t be located? We need to handle such situations to make sure our application does not go down. Every language provides ways to handle such exceptional scenario, so does Scala.

Scala, unlike Java, does not have the concept of checked exceptions. So, now you might be wondering why is it so?

Java’s checked exceptions force you to catch exceptions you don’t care to handle. That often leads to programmers placing empty catch blocks, thus suppressing exceptions instead of naturally propagating them to be handled at the right place. Scala does not do that. It lets you handle exceptions you care about and leave out the rest. What you don’t handle is propagated up automatically.

As you know, Scala is a functional and object-oriented language. The functional aspect of it dictates that side-effects should be eliminated, or at least minimized as much as possible.

Throwing an exception is a side-effect since it is not referentially transparent (i.e., it depends on the context of where the exception is thrown, for example, if the exception is thrown from inside a try block, it will be caught whereas if it is thrown outside of that try block, it will alter the flow of the program).

Scala supports three ways to handle exceptions:

1) try and catch block
2) Try block
3) Either block

Scala’s try and catch block is same as Java’s. We need to wrap the method that can throw any type of Exception in a try block and then catch the exception in the catch block. Let’s see this with the help of an example.

I have defined two exceptions:

class NegativeAgeException extends Exception {
  override def toString: String = "Age can not be negative."
}

class NotEligibleToVoteException extends Exception {
  override def toString: String = "The voter is not eligible to vote"
}

I have defined a method eligibleToVote(voter: Voter), which takes a case class Voter as an input parameter,

case class Voter(name: String, age: Int)

def eligibleToVote(voter: Voter) = {
  voter.age match {
    case age if age  throw new NegativeAgeException
    case age if age  throw new NotEligibleToVoteException
    case _ => s"${voter.name} can vote"
  }
}

Now, let’s create utility method canVote, which will call above method,

def canVote(voter: Voter) = {
try {
  eligibleToVote(voter)
} catch {
  case exception: NegativeAgeException => exception.toString
  case exception: NotEligibleToVoteException => exception.toString
 }
}

The result of the above call is:

canVote(Voter("Shivangi", -3))
res0: String = Age can not be negative.

canVote(Voter("Shivangi", 0))
res1: String = The voter is not eligible to vote. 

canVote(Voter("Shivangi", 24))
res2: String = Shivangi can vote.

We saw how we handled exception using try/catch block. Let see how we can handle exceptions in a functional style using Scala’s Try and Either.

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.

import scala.util.{Try, Success, Failure}
def decide(voter: Voter): Try[String] = {
 Try {
    eligibleToVote(voter)
  } match {
    case Success(value) => println(value)
      Success(value)
    case Failure(exception) => Failure(exception)
  }
}

Calling method decide with valid and invalid age whether the result is success or failure,

decide(Voter("Shivangi", -3))
res0: scala.util.Try[String] = Failure(Age can not be negative.)

decide(Voter("Shivangi", 24))
res1: scala.util.Try[String] = Success(Shivangi can vote.)

When we invoked the method with negative age, it resulted in a Failure[String] containing NegativeAgeException whereas invoking with a valid age resulted in a Success[String] containing proper response.

We have seen how we can handle exceptions try/catch block and Scala’s Try block. We will explore about handling exception using Either in next blog.

References:

  1. Pragmatic Scala
  2. Why Scala does not have the concept of checked and unchecked exception?

knoldus-advt-sticker


One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.