Exception handling in Scala

Exception Handling in Scala
Reading Time: 6 minutes

Hi all, in this blog we are going to observe how to do exception handling in Scala. To all my friends coming from Java background, bear with me this is going to be interesting. So, let’s start.

What’s Inevitable in the world of programming?

Well, there’s just one answer to that question: Failures. We can never guarantee that our application won’t face any failures in the future. We can’t even guarantee whether the application would not fail as soon as we open it for public use. You never know what external factor, and at what moment could trigger a failure in your application. Failures are an inevitable part of our journey be it in one’s life or in application development or in any other space. So the idea is, not to run from them, but to come up with resilient solutions that could handle such failures gracefully. We can categorize failures widely into two categories: Exceptions & Errors. Today our focus would be on the former one, Exceptions.

In scala, Exception and Error both are the subclasses of the class Throwable.

Exception vs Error

One question that I have seen people asking almost everytime is to differentiate between Exception and Error. I take this as an opportunity to provide an answer to this question as well.

Exception and Error are almost similar in the sense that both would ultimately crash the JVM. Yes, they are that powerful. The difference lies in their semantics.

Exceptions refer to something that went wrong with the program or the application itself. For example, a NPE(Null Pointer Exception). A NPE is something that could occur anytime in an application due to the lack of understanding when trying to fetch the value of an object, which in itself depends on some other entity to provide a value. If we think thoroughly while performing such a fetching, we can avoid a NPE. Thus, in general we can say that exceptions could be avoided.

On the other hand, an Error denotes something that went wrong with the system itself. For example, a Stack Overflow Error. This is system dependent and thus generally is not visible directly in the application. Try writing a recursion program in an infinite loop and very soon we will see a Stack Overflow Error. Your recursion program works fine till the time it completely fills the stack. Once there’s no space left in the system stack it throws an overflow error, and bang your application is dead.

Hope this clears the difference between Exception and Error. Further, let’s see Exceptions in Scala.

Exceptions & Scala

Scala is functional programming language. Except for the side effects that have a return type of Unit or (), everything else returns a value in scala. Scala treats everything as an expression and that is what makes scala such a powerful language. Scala is quite popular in the community because it treats everything as an expression returning a value.

My friends from Java background, please pay special attention to what I write next. “Scala treats throwing an Exception as an expression“. Wait, what? Throwing Exception is now an expression? Well ok, but if it is an expression can i assign it’s value to a variable? Also, if i can assign the value to a variable what would be the type of this variable? Lot’s of questions, let’s provide answers to these questions.

Yes, we can assign the value from throwing an exception to a variable, and the type of this variable is `Nothing`. Nothing is the subclass of all the types in the scala type hierarchy. It is also know as the bottom type. It has no value. We use Nothing to signal non-termination such as a thrown exception, program exit, etc. For example see the assignment below:

val ex:Nothing = throw new NullPointerException()
or simply just write,
val ex = throw new NullPointerException()

Looks good right? Now the big question what benefit we get by capturing the thrown exception in a variable? Well the answer to that brings us to the concept of Exception Handling in Scala.

Exception Handling

Exception handling in Scala behaves exactly like Java and works seamlessly with existing Java libraries. The difference is in its implementation in Scala. There are only “unchecked” exceptions in Scala. Also, throwing an exception is same as we do in Java. We create an object and use the throw keyword to throw the exception. The difference appears when trying to catch these exceptions.

Just like throwing an exception is an expression, handling an exception is an expression too. We handle exceptions using the same try-catch-finally blocks, it’s just that now we can store the returns from this block in a variable. Later, we can use this variable at multiple places to get the result from the try-catch block. Let’s see Exception Handling in scala with the help of examples:

object ScalaPlayground extends App {
  def getInt(throwException: Boolean): Int = {
    if (throwException) throw new RuntimeException("Exception was thrown forcefully.")
    26
  }

  try {
    getInt(true)
  } catch {
    case e: NullPointerException => println("Nothing will be printed.")
    case e: RuntimeException => println(s"Exception caught with message = ${e.getMessage}")
  } finally {
    println("Anything in the finally block will always be executed.")
  }

}

And the output for the above program would be:

Exception caught with message = Exception was thrown forcefully.
Anything in the finally block will always be executed.

See the style of handling multiple exceptions within a single catch block. As a result our catch block is capable of handling a NPE as well as a Runtime Exception. “Finally” block works the same way as in Java. If present, it executes anyhow.

Assigning the result of exception handling to a variable

Just like we stored the result of throwing an exception in a variable, we can store result from try-catch-finally in a variable as well. Let’s see an example to know how we can do that.

I did some slight modifications to our previous code, and assigned the value from try-catch block to a variable:

object ScalaPlayground extends App {
  def getInt(throwException: Boolean): Int = {
    if (throwException) throw new RuntimeException("Exception was thrown forcefully.")
    26
  }

  val exception = try {
    getInt(false)
  } catch {
    case e: NullPointerException => println("Nothing will be printed.")
    case e: RuntimeException => println(s"Exception caught with message = ${e.getMessage}")
  } finally {
    println("Anything in the finally block will always be executed.")
  }
  println(exception)
}

There is just a small change, this time I like to fetch the value of the integer from the getInt() method. So, I passed a false as a parameter to this method. As a result, final println statement would print the value to the console. Thus, we were able to capture the return value from a try-catch block and priont on the screen. The Output for this code is:

Anything in the finally block will always be executed.
26

As expected, the println statement from “finally” block gets printed to the screen with the result from getInt() method.

Return type of the variable holding the result

Well, we were able to store the result in a variable and later use it in the print statements. But, what is the return type of this variable? To answer this question, it is important to understand which factors would contribute to the type of this variable. Now, please pay attention folks.

It is only the try{} and catch{} block expressions that would contribute to defining the type of the variable.

Finally block is optional, and it does not influence the return type of the expression. We should use finally only for executing the side effects, like printing to a log file.

Ques: So what is the type of the variable “exception” in our case?

Ans: Well, the answer is simple. We just need to compare the returns from try and catch blocks and then through Scala type hierarchy we can deduce the correct type. Try block results in an Int and the catch block just defines println which are of type Unit() as shown earlier. So the final type would be {Int, Unit} => AnyVal. If instead of an Int, try block returns a reference type then the type of the variable would be AnyRef.

That was all about exception handling in Scala and how it differs from the way we do in Java. That said, I would be wrapping this post here. 🙂 Hope you guys like this post. Please share your comments and feedbacks with me. You can add them in the comments section below. If you like the content then please do share within your network. Until next time. 🙂

Conclusion

Following are the key points that we went through in the post:

  • We saw the difference between an exception and an error.
  • Understood Scala’s way of considering everything as an expression.
  • Examined how Exception handling in scala differs from Java.

I hope this blog would be helpful when dealing with exceptions while writing Scala code.

References

https://docs.scala-lang.org/

Knoldus-blog-footer-image

Written by 

Prashant is a Senior Software Consultant having experience of more than 3 years, both in service development and client interaction. He is familiar with Object Oriented Programming Paradigms and has worked upon Java and Scala-based technologies and has experience working with the reactive technology stack, following the agile methodology. He's currently involved in creating reactive microservices some of which are already live and running successfully in production, he has also worked upon scaling of these microservices by implementing the best practices of APIGEE-Edge. He is a good team player, and currently managing a team of 4 people. He's always eager to learn new and advance concepts in order to expand his horizon and apply them in project development with his skills. His hobbies include Teaching, Playing Sports, Cooking, watching Sci-Fi movies and traveling with friends.