Automatically and painlessly assigning error codes

Error codes are often cryptic and nonsensical to the end-user, and they’re not much fun for the developer either.  One problem I ran into was defining an error code numbering system.  After some thought, I determined that I most wanted to avoid manual labour and typos, e.g. sequential numbering for an error code argument.

A linear sequence of numbers makes typos easy.  Various sources of error, can crop up that way (e.g. “Oh!  You meant error #23292 not #23291?”).  The intent of distributing the numbers, is to make mistakes more apparent.   It’s worth noting that I don’t intend to categorize the errors by numerical ranges, so that’s a non-issue.  This is ond-and-a-half requirements in one: catch/avoid typos, catch/avoid communication errors.

Determining the error code for a new error condition should be painless.  It’s tedious to find the next unused number out of the set of error codes – this is the repetitive, boring behaviour that computers are meant for.

Additional constraints I had:

  • Code must always compile, and be in a state that properly indicates coding problems.  I’m using Eclipse and like the code-completion and on-the-fly-compilation.
  • Needs to work well for batch, as I had to back propagate the use of error codes to over 200 points where exceptions were being thrown.

My final solution follows.  It creates a lot of auto-generated classes, but there’s a good reason that is explained later.

  1. The programmer uses the custom exception class MyException normally.  The programmer doesn’t need to think about error codes.
  2. After check-in (for safety) of the working code, a search-and-replace program is run.
  3. The program finds all uses of classes named with the pattern MyException_n, where n is a number.  This class is explained later.  The set of these numbers are the error codes in use.
  4. The program searches for throwing of the vanilla MyException.  For each occurrence a new, unused error code is generated and the call is replaced with the throwing of an auto-generated MyException_x class, where x is the new error code.  The MyException_x class is written out.
  5. The modified code and new auto-generated exception classes are checked in.

MyException is a subclass of java.lang.Exception; while it has an error code field,  it doesn’t provide a public way of setting the value.  A single subclass of MyException exists initially, MyException_0.  MyException_0 looks like its parent ctor signature-wise, but it sets the value of the error code based on its own class name.

When the program is replacing a call to throw a vanilla MyException, it makes a copy of MyException_0  and replaces all occurrences of zero with the new error code number.  Since the implementation of MyException_0 uses its own class name to determine the error code value to set, this effectively changes the error code that will be seen at runtime.  This means that every throw is using a different exception type.

Now, before the complexity drives readers away, the only reason for such hackery is the code formatter.  The formatter moves the text around, so I can’t simply put in an error code of “42″ as a ctor argument to indicate an unassigned error, and do a search-and-replace on that.  Thrown exceptions are recognized by “throw new XXX“, which is probably going to be on the same line, but the ctor arguments have a good chance of being on a different line.  More generally, it’s that the Java language is flexible regarding whitespace/newlines and I don’t want to write anything that has to parse such variable data.

Rather than make the search-and-replace logic complex and prone to error, I am taking advantage of the fact that the class’s name can never be broken up. This makes the search-and-replace process simpler to implement and more robust against user error.

There are problems with this approach; it won’t work in every situation.  OO-wise, it’s terrible; that’s mitigated by putting the generated exceptions in its own package.  It’s also obvious these classes are not for direct consumption.  Compilation takes a longer, but the additional load is a few seconds.  The software is deployed in a single JAR, so I don’t have dependency concerns from putting all the auto-generated exceptions together.

While I’m sure it can fall apart or cause unacceptable constraints in other scenarios, for my scenario this approach adds a lot of value by automating a tedious and labour-intensive process.  All without adding new restrictions on my environment/behaviour.

I’m happy with the result.  I can develop as if I’d never heard of error codes.  When I need to think about it, I blindly run an ant target, compile, test, check-in.  Sixty seconds after start, I can go back to ignoring error codes.

Kenzo Ramen – thrice is the limit

When I first discovered Kenzo Ramen, I went on a brief crusade to bring as many friends as I could there. Partly to share the culinary delight, partly to validate that this was indeed what good ramen was like. I ended up going three times to Kenzo Ramen in December, probably having two bowls of ramen each time.

While I’ve had to take a break since then, I did enjoy their newly available pork broth based ramen the last time I went, the Tonkatsu Ramen:
Tonkatsu Ramen
The broth was very rich. One of my lunch companions told me that it wasn’t quite as rich as the same ramen that he had in California, but that could be construed as a good thing; that ramen was somewhat overwhelming. Delicious, and the ramen are always good regardless of the choice of broth.

True to my usual gluttony, I followed up with a Miso Ramen and Galbi combo. What can I say, other than that I have to work hard to get full on ramen. :)
Miso Ramen and Galbi

I’m sure I’ll go back to Kenzo Ramen once the seasons improve. I’ll stop blogging about it, though – I’m sure readers realize my enthusiasm for the restaurant at this point. ^_^

Follow

Get every new post delivered to your Inbox.