Using the finally block
A try...catch block can optionally be followed by a finally {} block. The code inside the finally block is always executed, even if an exception is not matched by any pattern in the catch block. The finally block is typically used to close any resource that is accessed inside the try block, such as a file or a network connection.
The following code shows how to use a URL to read a web page into a string:
import java.io.IOException
import java.net.URL
import scala.annotation.tailrec
val stream = new URL("https://www.packtpub.com/").openStream()
val htmlPage: String =
try {
@tailrec
def loop(builder: StringBuilder): String = {
val i = stream.read()
if (i != -1)
loop(builder.append(i.toChar))
else
builder.toString()
}
loop(StringBuilder.newBuilder)
} catch {
case e: IOException => s"cannot read URL: $e"
}
finally {
stream.close()
}
The finally block allows us to close InputStream, whether the reading of the page succeeded or not. This way, we will not leave a dangling open connection in case there is a network issue or a thread interruption.
Note that the preceding code is for illustrative purposes only. In a real project, you should use the following code format:
val htmlPage2 = scala.io.Source.fromURL("https://www.packtpub.com/").mkString
Now that you know how to use exceptions, we are going to define the concept of referential transparency and show how catching exceptions can break it. We will then explore better data structures that will let us manage errors without breaking referential transparency.