Heart containing Coding Chica Java 101

You are Exceptional! Error handling in Java

In Java, when the application runs into a situation that it cannot handle, it stops processing that request and instead throws an object that indicates something went wrong. This can be any child of java.lang.Throwable.

Unchecked Exceptions

There are children of java.lang.Throwable that are not typically ones that an application will be able to recover from – and therefore should just stop running, such as:

Therefore, these types of throwables need not be called out as possible behaviors in the application – they are unchecked by the Java compiler.

Checked Exceptions

Another child of java.lang.Throwable is java.lang.Exception. This is typically the base class (AKA parent) of all of the checked exceptions (AKA those that the Java compiler tries to help enforce are handled) that your application may want to catch and handle during processing.

Generally speaking, we don’t catch Exception directly, though, unless this is the outer-most catch block for an application. Within the application, we want to catch more specific types of exceptions and, where possible, handle either the recovery or error messaging returned for those scenarios.

Throwing Exceptions

When the Java application encounters a scenario that it cannot handle as happy-path, it throws an exception. This will look something like:

throw new IllegalArgumentException("count must be greater than 0");

In this one command we are:

  • Creating a new IllegalArgumentException instance with the message “count must be greater than 0”, and
  • Throwing that exception to stop the current method’s run.

At this point, the rest of the method’s logic is abandoned and the only thing coming out of the method is the thrown exception…unless we add some extra handling logic.

Try And Catch

If we call a method that may throw an exception and we want to handle that error scenario in some special way, we have to catch the exception and add that special handling logic.

However, we can’t just automatically catch everything…instead, the portions of the logic we want to catch exceptions for are put within a try block.

String valueToParse = "N/A";
int parsedValue = -1;
try {
   parsedValue = Integer.parseInt(valueToParse);
} catch (NumberFormatException nfe) {
  String errorMessage = 
        String.format(
            "Cannot parse %s to an integer.  Using default",
            valueToParse);
  System.out.println(errorMessage);
}
return parsedValue;

Here, only the call to the Integer.parseInt(String) method can result in any exception handling, as that is all that resides within the try {…} block. The catch (NumberFormatException nfe) says that we only want to catch the scenario where NumberFormatException is thrown and that thrown exception should be stored in a variable called nfe. Inside the catch block is the logic we should run if this happens. In this case, we’re going to output a message, but not do anything else. We may not need to, for example, in the logic in the try block, we want to assign the returned value to the parsedValue variable. However, since the parseInt call fails when the exception is thrown, we never get as far as having a value to assign to parsedValue, so it stays the -1 value from earlier.

You can have multiple catch blocks for a single try, but Java stops looking once it finds a match (similar to if/else-if/else-if…). Therefore, you want more generic catch blocks further down, so they don’t gobble up exceptions that have more specific handling expectations.

Try and Finally

A finally block can also be attached to a try block. When present, that indicates something that should ALWAYS happen, whether or not exceptions are thrown in the try block. Often, a finally block will contain cleanup style logic, such as:

  • Closing resources, such as database connections or file system files opened, and
  • Emitting metrics – when we want them whether success or failure.
try {
    ...perform work...
} finally {
   ...Emit metric to say how long the work took...
}

You can also have catch block(s) before the finally. Either way, the finally block will always run.

You are Exceptional! Error handling in Java

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.