Exception handling using enumerations in Java (I)

When I first read about Swift I quite liked its error handling.

In Java checked exceptions have gotten quite a bad rep but instead of throwing out the baby with the bathwater and getting rid of checked exceptions altogether, the way they do it in Swift seems to strike a good balance.

The thing that caught my eye however, was the use of enumerations instead of exception classes.

Using an enumeration as an error means that

  • Errors have a natural code (the enum value)
  • Errors are grouped together in a single place (the enum type)
  • There is no need to create contrieved exception hierarchies to differentiate between different types of errors

Fortunately Java has had enumerations since Java 5, an example exception using an enumeration fault code could look something like

The exception message above will just be the name of the enumeration value (ERROR_1 etc) which can work fine if the codes clearly indicate what the problem is. We can do better, however, by adding support for formatted messages and localization.

If we introduce an interface with default implementations for using MessageFormat and ResourceBundle we get more expressive messages without development overhead for creating new fault enumerations.

To use the interface our Exception example now becomes

The default implementation would simply create error messages similar to ERROR_1 [arg0, arg1, ...]. In order to get formatted messages we would also need to create the corresponding ResourceBundle property files. The base name can be customized but defaults to the fully qualified class name of the enumeration code type.

ExampleException2$Code.properties:

If message formats sound tempting but we would rather not define the required ResourceBundle property files that go with, we can opt to implement the method default String getDefaultFormat() { ... }:

We now have nicely formatted and potentially localized error messages all in one place.

Source code available in enum-exceptions on GitHub.

While this is nice, what about exception handling? If we retrieve the fault code from the exception when we catch it, we can of course implement branching logic based on the value, e.g. something like:

In some cases this will work just fine but if we want to handle different fault codes or ordinary exceptions the same way we are in a bit of a bind as the fault code approach effectively breaks the multicatch feature introduced in Java 7. The switch case above does for the fault code what the catch statement is already doing at the exception level.

Would it not be great if we could catch the code instead of the exception?

To do this we need to extend the Java syntax which is discussed in the next post.

Leave a Reply