C++ – How to Design Exceptions

cdesignexceptionsstl

I'm struggling with a very simple question:

I'm now working on a server application, and I need to invent a hierarchy for the exceptions (some exceptions already exist, but a general framework is needed). How do I even start doing this?

I'm thinking of following this strategy:

1) What is going wrong?

  • Something is asked, which is not allowed.
  • Something is asked, it is allowed, but it does not work, due to wrong parameters.
  • Something is asked, it is allowed, but it does not work, because of internal errors.

2) Who is launching the request?

  • The client application
  • Another server application

3) Message handing : as we are dealing with a server application, it's all about receiving and sending messages. So what if the sending of a message goes wrong?

As such, we might get following exception types:

  • ServerNotAllowedException
  • ClientNotAllowedException
  • ServerParameterException
  • ClientParameterException
  • InternalException (in case the server does not know where the request is coming from)
    • ServerInternalException
    • ClientInternalException
  • MessageHandlingException

This is a very general approach to define exception hierarchy, but I'm afraid that I might be lacking some obvious cases. Do you have ideas on which areas I'm not covering, are you aware of any drawbacks of this method or is there a more general approach to this kind of question (in the latter case, where can I find it)?

Thanks in advance

Best Answer

General remarks

(a bit opinion-biased)

I'd typically not go for a detailed exception hierarchy.

Most important thing: an exception tells your caller that your method failed to complete its job. And your caller must get notice about that, so he doesn't simply continue. That works with any exception, no matter what exception class you choose.

Second aspect is logging. You want to find meaningful log entries whenever something goes wrong. That also doesn't need different exception classes, only well-designed text messages (I suppose you don't need an automat to read your error logs...).

Third aspect is reaction of your caller. What can your caller do when he receives an exception? Here it can make sense to have different exception classes, so the caller can decide whether to retry the same call, to use a different solution (e.g. use a fallback source instead), or to give up.

And maybe you want to use your exceptions as the base for informing the end user about the problem. That means creating a user-friendly message besides the admin-text for the log file, but doesn't need different exception classes (although maybe that can make the text generation easier...).

An important aspect for logging (and for user error messages) is the ability to amend the exception with context information by catching it at some layer, adding some context information, e.g. method parameters, and re-throwing it.

Your hierarchy

Who is launching the request? I don't think you'll need the information who was launching the request. I can't even imagine how you know that deep inside some call stack.

Message handling: that's not a different aspect, but just additional cases for "What is going wrong?".

In a comment, you talk about a "no logging" flag when creating an exception. I don't think that at the place where you create and throw an exception, you can make a reliable decision whether or not to log that exception.

The only situation I can imagine is that some higher layer uses your API in a way that will sometimes produce exceptions, and this layer then knows that it need not bother any administrator with the exception, so it silently swallows the exception. But that's a code smell: an expected exception is a contradiction in itself, a hint to change the API. And it's the higher layer that should decide, not the exception-generating code.