Scala Tutorials Part #24 - Exception Handling
Originally Posted On : 09 Oct 2017
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.
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.
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.
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.
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.