Exceptionally Cheeky

Sometimes in Java we might want to write a function to classify an error and throw the correct exception. Let’s assume we want to write something like this:

public void throwCorrectException(int statusCode) {
   if (statusCode >= 400 && statusCode < 500 {
      throw new ClientException("Foo");
   }
   throw new BadHttpRequest("Bar");
}

The above code is fine, but it turns out to have a practical problem when used in a parent function. I’ve had similar issues with common validation errors, or something to review a caught exception and rethrow the right one. Here’s an example of the problem:

public String getFromServer() {
   Response response = getDataFromServer();
   if (response.getStatus() == 200) {
       return response.getBody();
   }
   throwCorrectException(response.getStatus());
} // compiler error... doesn't return a value...

Ignore how the above example looks a bit fictional, it illustrates the problem that this function, though in practice all paths end in return or exception, doesn’t compile because it doesn’t appear to return.

The Cheeky Exceptional Return Workaround

Here’s the same code written again, but with the workaround in place.

public <T> T throwCorrectException(int statusCode) {
   if (statusCode >= 400 && statusCode < 500 {
      throw new ClientException("Foo");
   }
   throw new BadHttpRequest("Bar");
}

public String getFromServer() {
   Response response = getDataFromServer();
   if (response.getStatus() == 200) {
       return response.getBody();
   }
   return throwCorrectException(response.getStatus());
}

Did you see the trick? Although all paths result in exception, it’s perfectly ok to make throwCorrectException appear to return anything the caller wants… it doesn’t actually return anything!

Similar, the throw function can be called and its (non existent) return value can be passed through the return statement on the last line of the calling function.

And thus is compiles and we all wonder what we just did.

I blame JavaScript!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s