Scala Tutorials Part #24 - Exception Handling


Exception Handling

This is part 24 of the Scala tutorial series. Check here for the full series.

Index

Introduction

Exceptions occur when normal flow of execution gets disrupted. It is usually handled in a try-catch block with an optional finally block. They are created from the root class Exception and an instance of the Throwable class is used to throw exception messages.

Below is a visual representation of how the class hierarchy is designed in the JVM.

Exception hierarchy

And then it branches into checked exceptions which needs to be handled by the caller, ones such as FileNotFoundException, OperationNotSupportedException etc., and unchecked exceptions such as OutOfMemoryException, NullPointerException etc., It is a common confusion that checked exceptions are compile time and unchecked exceptions happen at run time. The truth is that there is no such thing as compile time exception and everything happens at run time. The difference between both is how they are handled. Checked exceptions are forced by the compiler to be handled during compile time/build time while unchecked exceptions aren’t.

Checked exception

Scala handles exceptions in a slightly different manner and for a good reason.

The case of Checked Exceptions

Scala does not have checked exceptions. The compiler does not enforce exceptions to be handled. For example, the below code which is a direct translation of the above java code block compiles just fine.

  readFile("somefile.txt")


def readFile(path:String) = {

val file = new File(path)

val fileInputStream = new FileInputStream(file)

println(fileInputStream.read())

}

It will throw an error if there is no such file is present only at the run time. Checked exceptions have always been a topic of controversy. Here is a good article on why checked exceptions are bad. This feature is at least controversial if not bad and hence the language developers decided to drop this.

Handling exceptions with try-catch

Like java, Scala has try/catch to handle exceptions. Let’s take a look at the same file read example.

readFile("somefile.txt")


def readFile(path:String) = {

try {
val file = new File(path)

val fileInputStream = new FileInputStream(file)

println(fileInputStream.read())
}

catch {

case f : FileNotFoundException => println("File not found")
case e : IndexOutOfBoundsException => e.printStackTrace()
case _ : Throwable => println("Unknown exception")

}

finally {
println("Inside finally block")
}

}

try is similar to Java which contains code that could cause an Exception. The catch block however is different and it uses pattern matching. The _ operator here is used as a wildcard operator which matches other than the ones above it. Everything else should be similar to its Java counterpart including the finally block.

Conclusion

What we have explored in this article is just a beginning. Scala being a multi-paradigm language has many ways to deal with scenarios that could cause errors. We already saw some of those in part 1 where we cannot leave a variable uninitialized preventing null pointer to a certain degree and also the Option/Some/None pattern to deal with undecidable situations.

General best practices such as giving descriptive error messages, not to catch Error, not to ignore exceptions etc., still apply.


Tagged Under


Scala


Search this website...




Keeping up with blogs...

I blog occasionally and mostly write about Software engineering and the likes. If you are interested in keeping up with new blog posts, you should follow me on twitter where I usually tweet when I publish them. You can also use the RSS feed , or even subscribe via email below.

Feedio Subscribe


Share & Like

If you like this post, then you can either share/discuss/vote up on the below sites.



Thoughts ...

Please feel free to share your comments below for discussion

Blog comments powered by Disqus