Scala supports the Java semantics for exception handling, but the syntax for try-catch is quite different. Also, Scala does not distinguish between checked and unchecked exceptions—it treats all exceptions as if they’re unchecked.
In Scala you throw exceptions just like in Java; for example:
| throw new IllegalArgumentException |
Remember, you can leave out the empty parentheses after the class name when creating an instance and semicolons are optional.
Also, you can use a try block just like in Java. Scala, however, doesn’t force you to catch exceptions that you don’t care about—not even checked exceptions. This prevents you from adding unnecessary catch blocks—you simply let the exceptions you don’t care to catch propagate up the chain. For example, if we want to call the Thread’s sleep, then instead of this:
| // Java code |
| try { |
| Thread.sleep(1000); |
| } |
| catch(InterruptedException ex) { |
| // Losing sleep over what to do here? |
| } |
we can simply write this:
| Thread.sleep(1000) |
Scala did not insist that we write an unnecessary try-catch block.
Of course, you certainly should handle exceptions you can do something about—that’s what catch is for. The syntax of catch is quite different in Scala; you use pattern matching for handling the exceptions. Let’s look at an example of try-catch. First, here’s the code that may throw different exceptions:
ExceptionHandling/Tax.scala | |
| object Tax { |
| def taxFor(amount: Double) = { |
| if (amount < 0) |
| throw new IllegalArgumentException("Amount must be greater than zero") |
| |
| if (amount < 0.01) |
| throw new RuntimeException("Amount too small to be taxed") |
| |
| if (amount > 1000000) throw new Exception("Amount too large...") |
| |
| amount * 0.08 |
| } |
| } |
Let’s call the taxFor method and handle some of the exceptions.
ExceptionHandling/ExceptionHandling.scala | |
| for (amount <- List(100.0, 0.009, -2.0, 1000001.0)) { |
| try { |
| print(s"Amount: $$$amount ") |
| println(s"Tax: $$${Tax.taxFor(amount)}") |
| } |
| catch { |
| case ex: IllegalArgumentException => println(ex.getMessage) |
| case ex: RuntimeException => { |
| // if you need a block of code to handle exception |
| println(s"Don't bother reporting...${ex.getMessage}") |
| } |
| } |
| } |
Here’s the output from the code, with a partial stack trace:
| Amount: $100.0 Tax: $8.0 |
| Amount: $0.009 Don't bother reporting...Amount too small to be taxed |
| Amount: $-2.0 Amount must be greater than zero |
| Amount: $1000001.0 java.lang.Exception: Amount too large... |
| at Tax$.taxFor(Tax.scala:9) |
| ... |
The taxFor method may throw three different exceptions depending on the input. The catch block has case statements for handling two of these exceptions. The output shows how these blocks handled these two exceptions. The third unhandled exception results in termination of the program with details of the stack trace being printed. The order of the case statements is important, as we discuss in the next section.
In the previous example, we saw how to catch specific exceptions. If we want to catch just about anything thrown, we can catch Throwable and also use an _ (underscore) for the variable name if we don’t care to know the exception details, as shown in the following example:
ExceptionHandling/CatchAll.scala | |
| for (amount <- List(100.0, 0.009, -2.0, 1000001.0)) { |
| try { |
| print(s"Amount: $$$amount ") |
| println(s"Tax: $$${Tax.taxFor(amount)}") |
| } |
| catch { |
| case ex : IllegalArgumentException => println(ex.getMessage) |
| case _ : Throwable => println("Something went wrong") |
| } |
| } |
The catchall case caught all but the IllegalArgumentException, which had its own special catch block, as we see in the output:
| Amount: $100.0 Tax: $8.0 |
| Amount: $0.009 Something went wrong |
| Amount: $-2.0 Amount must be greater than zero |
| Amount: $1000001.0 Something went wrong |
Scala also supports the finally block—just as in Java, it’s executed irrespective of whether the code in the try block threw an exception.
Just as catching checked exceptions is optional in Scala, so too is declaring checked exceptions optional. Scala doesn’t require us to declare what exceptions we intend to throw. See Extending Classes for issues related to intermixing the code with Java.
18.189.31.26