Unexceptional Uses of Java Exceptions

Oct 01, 2018

What’s an exception?

Oracle, the current owners of Java, says:

Definition: An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.

Java (and many, if not most, other programming languages) provide an Exception as a way to handle errors. When a severe error occurs, the program creates an object and “throws” it. It travels up the call stack until another object that is capable of handling the problem “catches” it. If no one catches it, the error can cause the thread, and even the whole program, to exit.

Depending on how your code uses them adding a try/catch block to your code can be expensive, even if the exception is never thrown.  If your code throws, the impact can be worse.

They also look a lot like a GOTO. ’nuff said.

To me, exceptions are for exceptional events. We’re running out of memory. An external resource is gone. A reference became a null.

When an Exception is not Exceptional

Here is the signature for a commonly used method in QuickFixJ, an API I use:

public String getString(int field) throws FieldNotFound

It’s a method for retrieving the String value of a field in a FIX (Financial Information eXchange) message. If you ask for a value that is not there, it throws a FieldNotFound exception.

So, if you are working in an environment like mine, where whether or not a field exists is part of the message semantics and not an error, you end up doing this:

public String tagAsString(int tagId) {
  if (quickfixMessage.isSetField(tagId)) {
    return quickfixMessage.getString(tagId);
    return "";

I work on software that routes a few million messages a day. It determines where to send them by checking which fields are set and what their values are. To avoid the expense of the exceptions, I have to check the value twice.

For people that work with a strictly enforced dictionary, a missing tag might be an exceptional condition. They’re like that TV lawyer that only asks questions she knows the answer to. Those of us that serve at the mercy of paying customers have to code around the developer’s opinions about FIX messages.

To be fair to QFJ, I did a pull request and asked that the exception be replaced with an Optional, and the compromise was to add a getOptionalString. This alleviated the problem where an Optional is useful and has that “expose your datatypes in your object names” vibe that I miss from old Win32 code. (Just like I miss buffer underflows when I burn CDs.)

Spring JDBCTemplate and Empty Results

I recently started using Spring’s JdbcTemplate, and found myself writing this:

try {
  Map<String, Object> row = getJdbcTemplate().queryForMap(sql, sessionMemberId);
  return Optional.of(parseRow(sessionMemberId, row));
} catch (EmptyResultDataAccessException dae) {
  return Optional.empty();

Yes, an SQL query that results in an empty set is an Exception. To quote a StackOverflow: answer “Now the correct way is not to catch this exception or EmptyResultDataAccessException, but make sure the query you are using should return only one row.”

So, rather than use your database to store data and then query it for relationships, you should know the relationships in advance. And if you don’t, let the app crash with an uncaught exception.

Does a query returning an empty set “disrupt the normal flow of the program?”

In the case of the SQL query, just no. Never. Absolutely not. Why does EmptyResultDataAccessException exist? In what world does an empty result “disrupt the normal flow of the program?”

Let’s look at another snippet of code in the same program, using the same Spring object:

List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
if (rows.isEmpty()) {
  return new ArrayList<>();

In this case, I’m querying for a list. If the result set is empty, the return is an empty list.

So, I’d have to say that an empty result doesn’t disrupt the normal flow of the program. EmptyResultDataAccessException is enforcing an opinion, not communicating an error.

Java is a verbose and often noisy language. Let’s try to not make it worse with unneeded try/catch blocks.

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.