Wednesday 30 November 2011

Adding context to exceptions

Exceptions are strange beasts: they percolate up the calls tree against the flow of logic, like salmon making their way up river. Normally, this is exactly what you want: as the call stack unwinds, each level of abstraction has its chance of catching or forwarding the error.

Recently, I had the chance of extensively reworking the exception messages of the boost program_options library. The idea was to make the exception text so clear and unambiguous that they could be understood by the average (non-professional programmer) user. After all, it is not only c++ programmers who mistype options on the command line (try "ls --humam-readable"). 

The key was to provide enough context to the exception text so that the user would now exactly where and how their command line options were being misunderstood.

My current patch for boost::program_options gathers this context and passes it all the way down the call tree where ever an exception might occur. Unfortunately, this means function calls all over the library are polluted with yucky extra parameters whose sole purpose is to be thrown. Layers of abstraction are being violated, and the whole library has been filled with (well commented!) spaghetti.

This weekend I am going to refactor so that each level of code will catch and rethrow any exceptions, adding appropriate context that only it should know about. There will be extra bookkeeping in the exceptions but everyone else should be a lot happier.