All about to know Exception Handling in Scala

Reading Time: 3 minutes

Introduction

In this blog, we’re going to talk about exception handling in Scala. We’ll also explore different ways of handling Exception by using different constructs provided by Scala.

What’s an Exception ?

An exception is an event that interrupts the normal flow of a program. Exception handling is the process of responding to an exception. In Scala, Exceptions are either checked or unchecked. Scala allows only unchecked exceptions, so we won’t see the exception at compile time.

1. try/catch/finally

In Scala, we can handle exceptions using the try/catch/finally construct, very similar to the Java one.

class TryCatchFinally{
  def divide(num1:Int, num2:Int): Unit = {
    try{
      println(num1/num2)
    }catch{
      case e: ArithmeticException => println(e)
      case ex: Throwable =>println("found an unknown exception"+ ex)
    }finally{
      println("All remaining code is executing...")
    }

  }
}
object TryCatchFinallyExample extends App{
    val e = new TryCatchFinally()
    e.divide(10,2)
    e.divide(10,0)
}

Output:
5
All remaining code is executing...
java.lang.ArithmeticException: / by zero
All remaining code is executing...

Some important points

  • Try blocks should contain “risky” code.
  • No matter what happens beforehand, the code inside the finally block will always be execute – it’s handy, for instance, whenever we want to make sure a resource, like a database connection, is close.
  • In the catch section, case statements can be use to match different exception types.

2. Try/Success/Failure

Try/Success/Failure is an alternative to using Option/Some/None in Scala.

Specifically, Failure returns the Exceptions you want when the code in your method fails.

import scala.util.{Failure, Success, Try}

object TrySuccessFailureExample extends App{
  def divide(num1:Int, num2:Int): Try[Int] = Try{
    num1/num2
  }
}
object TrySuccessFailure extends App{
  val result1= TrySuccessFailureExample.divide(20,10)
  result1 match {
    case Failure(e) => println(s"Failure ${e} has been occurred.")
    case Success(_) => println(result1)
  }
  val result2= TrySuccessFailureExample.divide(20,0)
  result2 match {
    case Failure(e) => println(s"Failure ${e} has been occurred.")
    case Success(_) => println(result2)
  }
}

Output:
Success(2)
Failure java.lang.ArithmeticException: / by zero has been occured.

3. Option/Some/None

An Option[T] object can be either Some[T] or None, which represents a missing value.

Scala uses the option type frequently, which is comparable to Java’s null value, which indicates no value.

class OptionSomeNoneExample extends App {
  def toInt(s: String): Option[Int] = {
    try {
      Some(Integer.parseInt(s.trim))
    } catch {
      case e: Exception => None
    }
  }
}
  object OptionSomeNone extends App{
    val e = new OptionSomeNoneExample()
    println(e.toInt("1"))
    println(e.toInt("Scala"))
}

Output:
Some(1)
None

4. Either

Either work the same as the Option in Scala, the only difference with Either are you can return a String that describes the problem that occurred.
There are two children of Either class named Right and Left. Right is the same as the Some and Left is the same as the None class.

class EitherExample{
  def division(num1: Int, num2: Int): Either[String, Int] =
  {
    if (num2 == 0)
      Left("No division Possible!")
    else
      Right(num1 / num2)
  }
}
object EitherExample extends App{
  val res=new EitherExample()
  val x1=res.division(10, 2)
  x1 match{
    case Left(l) => println("Left: " + l)
    case Right(r) => println("Right: " + r)
  }
  val x2=res.division(10, 0)
  x2 match{
    case Left(l) => println("Left: " + l)
    case Right(r) => println("Right: " + r)
  }
}

Output:
Right: 5
Left: No division Possible!


5. throw Keyword in Scala

In your code, you can also explicitly throw exceptions. You can throw an exception in Scala using the throw keyword. Throwing a custom exception is the main use of the throw keyword.

class ThrowKeyword {
  def validate(age:Int): Unit ={
    if(age<18)
      throw new ArithmeticException("You are not eligible")
    else println("You are eligible")
  }
}
object ThrowKeyword extends App{
  val validAge=new ThrowKeyword()
  validAge.validate(20)
  validAge.validate(10)
}

Output:
You are eligible
You are not eligible

6. throws Keyword in Scala

Scala provides the throws keyword for declaring exceptions. Exceptions can be declared in the method definition.It informs the caller function that this method may throw this exception. To prevent abnormal termination of the program, it is helpful to enclose the code in a try-catch block.

import com.sun.media.sound.InvalidFormatException

class ThrowsKeyword {
  @throws(classOf[InvalidFormatException])
  def validate(): Int ={
    "Scala".toInt
  }
}
object ThrowsKeyword extends App{
  val isValid=new ThrowsKeyword()
  try{
    isValid.validate()
  }catch{
    case ex : NumberFormatException => println("Exception handled here!")
  }
  println("Rest of the code executing.")
}

Output:
Exception handled here!
Rest of the code executing.

Conclusion

The purpose of this article was to discuss Scala’s support for exception handling. It is a trade-off between code accessibility and code reusability when choosing between catch objects and Try/Success/Failure. In Scala, they provide an easier method of achieving functional composability than try/catch/finally.

Reference

https://docs.scala-lang.org/overviews/scala-book/functional-error-handling.html

Scala Future

Written by 

Pappu Bhardwaj is a Software Intern at Knoldus Inc. in Noida. He has completed his B.Tech from the KIET Group of Institution, Ghaziabad. He is recognized as a good team player, a dedicated and responsible professional, and a technology enthusiast. He is a quick learner & curious to learn new technologies. He is passionate about Competetive Programming. He loves to play cricket and wildlife photography.