Let us be lazy and not modify subroutine test in listing 3. Instead, we’ll write another subroutine to call test and handle the exceptions. The new subroutine is listed in listing 4.
Listing 4: | tryandcatch |
Line 3 is a try statement. The block may include any number of statements. A try statement differs from a normal block because it can expect certain exceptions thrown either directly in the block, or indirectly by a subroutine that get invoked eventually during the execution of the code in the block.
A try statement needs at least one catch statement. In this case, we have three. Line 7 catches specifically a BadPath exception, whereas lines 11 and 15 catch BadInt and TooBig exceptions, respectively.
This gives us the ability to fine tune how each individual kind of exception is handled. Of course, in this case, they are all handled the same way. To save us some typing, we can rewrite the code as in listing 5.
Listing 5: | tryandcatch |
In this modified code, the catch statement catches any exception that is a subclass of Exception, and prints the message from it. This means that you can have many class hierarchies of exceptions, and use the inheritance to control the scope of catch statements.