Thread: Exception handling in a large project

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262

    Exception handling in a large project

    Hello all,

    I have a question here: In a large C++ project, how would you do exception handling?

    In my last project, which was in PHP, I designed the exception handling structure. I simply used exception classes. There were several exception classes like "ExternalException", "CallingFunctionException" and a few others. Based on this, a few other exception classes were based ("InvalidParameterException" on CallingFunction, "InvalidPermissionException" on External, etc). I think it was quite useful - since it could automatically find out which programmer should likely be responsible for fixing the problem quite nicely - but in general, this would be quite an overkill for C++ projects.

    I could simply have one layer of exception classes, for every possible exception ("FileNotFoundException", "InvalidPermissionException", etc). On this method, a catch can easily be done for only several types that can be handled by the function.

    For multiple exceptions, however, you have to override the constructor manually for every base class. So every exception takes a few lines (With eg. InvalidPermissionException(const char *what) : ExceptionBase(what) {}).
    Some time ago I simply used a class that would be called like:
    Code:
    Exception<InvalidPermissionException>::doThrow("Message here");
    This made it possible to declare an extra exception really easy (class SomeException : public ExceptionBase {}).
    Another project, I simply made a "#define". I know they're considered evil in general, but again, I could simply declare an exception with a single macro, it would automatically create a class and add the constructor needed.

    That's about the summary of my ideas. What do you guys think is the best method? Is there a better method than the ones I mentioned and if not, which method do you think is best?


    Thanks,
    EVOEx

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I don't think a macro would be that evil here.

    But how does the doThrow version work exactly?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Thanks for your reply.

    The Exception class had a static member called doThrow. This would create the class passed in brackets using the template argument. These classes could only be instantiated using this function. Then the function would set the exception message passed to the function (not through a constructor, as this avoided using a constructor for all classes).
    The exception base class had this exception generator class as a friend. So it could directly write to the exception pointer (or I used an interface function that existed in the exception base, I don't remember).

    So, do you guys have a better method? Or would you guys use exceptions at all? (Ah, I will use it unless speed is critical in the application, but I would just like to know)


    Thanks

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by EVOEx
    For multiple exceptions, however, you have to override the constructor manually for every base class.
    That would not really be overriding the constructor, but simply defining a constructor for the new class. Personally, I do not bother too much and simply manually define the exception classes with a constructor, but I suppose a macro would help if you really wanted to reduce the amount of typing.

    Incidentally, I typically derive my exception classes from either std::logic_error or std::runtime_error, and hence keep the respective constructor's signature such that it takes a std::string instead of a const char*.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Thanks for your answer (and happy birthday :P, I noticed on the front page).

    What you're saying sounds good. I don't bother creating a constructor for every class either per se, but my experience is that it becomes an unreadable mess. I guess what you're saying is best for me, using those two exceptions as base classes. And I guess I will use macro's here, since I consider this a lot more readable:
    Code:
    DECLARE_EXCEPTION(InvalidArgumentException, std::logic_error);
    A lot better than:
    Code:
    class InvalidArgumentException : public std::logic_error { InvalidArgumentException(const std::string &what) : std::logic_error(what) {} };
    Thanks,
    EVOEx

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    In my last [...] quite an overkill for C++ projects.
    I use this approach in all of my code--in languages that support exceptions. Having several dozen exception classes that defines the kind of exception without further inspection is never overkill. This approach provides too many advantages to ignore.

    I could simply have one [...] handled by the function.
    I don't like the idea of a single layer. If I need to deal with 'FileNotFoundException' and 'InvalidPermissionException' at a particular level I may have to duplicate code, separate the exception handling logic into an otherwise useless function, or "translate" the exception.

    Exception<InvalidPermissionException>::doThrow("Me ssage here");
    I use something similar. You throw and catch 'exception<TAG>::type'. The 'TAG' can be any type you like. The meta-programming handles all the work you're afraid of duplicating.

    Another project, I simply made a "#define".
    Using a macro for this is fine. (I just wouldn't suggest that you use a macro.)

    Happy birthday, LL.

    Soma

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by EVOEx
    I guess what you're saying is best for me, using those two exceptions as base classes.
    Yes, whether directly or indirectly. I find that it also makes sense to just use one of their immediate derived classes at times, like std::invalid_argument.

    Quote Originally Posted by EVOEx
    And I guess I will use macro's here, since I consider this a lot more readable:
    I might name the macro DEFINE_EXCEPTION instead, in view that this is also a declaration of the InvalidArgumentException class:
    Code:
    class InvalidArgumentException;
    Oh, and thanks for the birthday wishes
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    So the best solution is to use multiple layers, probably... You may be right there.

    And I guess I'll use the macro to define them - and you're right btw, your name is better .


    Thanks a lot, all of you .

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem Displaying a Struct
    By rockstarpirate in forum C++ Programming
    Replies: 16
    Last Post: 05-05-2008, 09:05 AM
  2. Need simple code for large file handling
    By spiit231 in forum C Programming
    Replies: 4
    Last Post: 02-27-2008, 01:05 AM
  3. ATL exception handling
    By rzcodeman in forum Windows Programming
    Replies: 1
    Last Post: 06-10-2004, 06:19 PM
  4. exception handling classes in IRIX....?
    By BrianK in forum C++ Programming
    Replies: 2
    Last Post: 01-28-2003, 03:02 PM
  5. exception handling and linked lists
    By s0ul2squeeze in forum C++ Programming
    Replies: 0
    Last Post: 04-08-2002, 02:39 AM

Tags for this Thread