Exceptions

We will lean on the Effective Java Exceptions guidelines.

A few practical implications are reiterated here.

  • Only throw checked exceptions (contingencies) when the immediately surrounding method is expected to handle it.
    • This could be an alternative control flow (a method may return an integer or throw an exception as alternative return value)
    • Always document the exception
    • Always handle the exception in the immediately surrounding method. If the exception needs to be rethrown, wrap it in a runtime exception (fault)
  • Throw unchecked exceptions (faults) for everything else
    • This could be I/O errors, faulty parameters, invalid invariants (programming errors), etc.
    • Never document the exception on the method. Document it in the exceptions documentation (For instance: "This exception may be thrown by any method on I/O trouble") and/or in the package description (For instance: "Any method in this package may throw IllegalArgumentException" on parameters that are null or the empty string, if not otherwise documented")
    • Catch faults at well defined points in the code by using Fault Barriers. These may catch all runtime exceptions, or a well defined subset. Fault barriers may handle the exception (for instance retry), report it (for instance log it or åresent (a version of) it to the user), or explicitly silence it if it is known to be harmless.
    • Always install a Fault Barrier at the outermost method of a thread, either explicitly or implicitly created (for instance in main(), Thread.run(), and methods in a new thread by frameworks such as Servlets, Web Service frameworks or JMS)

Generally, exceptions should be considered part of the API, and thus exceptions for a given java package should be defined in that java package. For instance, a package defining the interface for JMS messaging should define the expected exceptions (contingencies as well as faults) in that package.

However, runtime exceptions from the java.lang-hierarchy may also be used, if they describe the fault sufficiently - e.g. java.lang.IllegalArgumentException.

Beware of checked exceptions from the java.* and javax.* hierarchy. Many describe faults rather than contingencies, and should be wrapped in a bitrepository-specific fault.