A neat way of handling common C++ exceptions

Another slightly edited post from my old C++ blog. Again, you may have seen this one before.

This post is a quasi follow-up to the  “little exception shop of horrors”. As I mentioned in that post, I believe the reason for dumping all the exception handling code into a single header file was a misguided attempt at avoiding code duplication. No, I didn’t write that code, so I can only speculate as to why it was done. I inherited the project that contained this code and the reasons were lost in the mists of time. I did file it under “sound idea but bad execution”. It doesn’t fix the problem and you still have code duplication as the preprocessor will do the duplication work for you. Ah well, at least to don’t have to type the code in yourself multiple times. I couldn’t help but think that there must be a better way.

I more or less forgot about the whole thing as the code was about to be retired anyway. At some point I was talking to a colleague about it and he showed me a much nicer way of addressing this problem without the code duplication and in a much cleaner fashion. Start with a try/catch block like this:

try {
  // ... Lots of code here
}
catch (...) {
  handle_common_exceptions();
}

The handler function looks like this:

void handle_common_exceptions() {
  try {
    throw;
  }
  catch (specialised_exception const &ref) {
    // handling code
  }
  catch (another_sub_exception const &ex) {
    // ... more exception handling code ..
  }
  catch (std::bad_alloc const &ref) {
    // ... even more
  }
}

The elegant part is that you rethrow the exception that has been caught in the original try block and then handle those exceptions that your code actually can handle at this point. Normally, catch (…) is only useful if you are in a piece of code which requires you to stop any exceptions from escaping. You can’t determine what the actual exception is, so you can’t handle it appropriately. The only thing you can do is to say “oops, sorry”.

Rethrowing the exception inside the catch-all handler does restore access to the exception information so you can handle the exceptions that are appropriate at the point of the catch handler. As long as you don’t add another catch-all handler inside the handler function (note that I didn’t), those exceptions that you cannot handle
at this point propagate further up the call chain as they escape the handler function due to the rethrow.

Quite neat, don’t you think? Thanks to Alan Stokes for showing this technique to me.

The little exception shop of horrors

This post first appeared on my old C++ blog. You might have seen it before.
I think by now we can all agree that exceptions are generally a good thing in C++. They allow us to separate the error handling from the general flow of control inside a program and also enable us to handle errors at the most appropriate point. More often than not, the best point to handle errors is quite far removed from the source of the exception.

Imagine my surprise when I came across the following gem that was almost worthy of the Daily WTF:

catch (std::string ex) {
  // Do something horrible with the exception
}
 catch (const char *ex) {
   // Eh?
 }
 catch (int i) {
   // Uh oh
 }

I guess in some circles, being able to throw any sort of POD or object as an exception is considered a good thing. It’s not necessarily something I consider a good idea. For the moment we’ll also gloss over the advisability of catching exceptions by value. That doesn’t mean I’m condoning that sort of coding, especially not when you’re catching types that might trigger memory allocations when copied.

But wait, it gets better. You thought that the code snippet above was part of a larger chunk of code that I omitted, didn’t you? Well, it actually wasn’t – it was all parked in a header file. Obviously in the interests of brevity I removed the code that actually handled the exceptions while preserving the full structure of the code in the header file.

So what the heck is going on here then? It looks like in order to avoid duplication of code – always a worthy goal – the above header file got include wherever “needed”, so at least one of the project’s source files was full of code like this:

void doSomething() {
  try {
    // Lots of processing that might throw
  }
#include "catch_clauses.H"
}

Pass the Stroustrup, I need to refactor a developer or three…