Alex Rivera | Logout

How to throw good exceptions?

Asked 2009-02-17T10:39:25.503
13

I heard you should never throw a string because there is a lack of information and you'll catch exceptions you dont expect to catch. What are good practice for throwing exceptions? do you inherit a base exception class? Do you have many exceptions or few? do you do MyExceptionClass& or const MyExceptionClass& ? etc. Also i know exceptions should never been thrown in destructors

i'll add that i understand design by contract and when to throw exception. I am asking how i should throw exceptions.

Edit
Report

4 Answers

1

I always throw an exception with a message of where it occurred and what caused it to happen:

throw NException("Foo::Bar", "Mungulator cause a stack overflow!");

You can then use these strings in messageboxes etc.

I always catch via

catch (NException& ex) { ... }

If you running windows you can pass the error value and have a function derive the error message. The best example of this is in Windows via C/C++ by Jeffrey Richter.

answered 2009-02-17T11:19:54.487
1

Throwing pointers is probably not a good thing, as it complicates ownership of the thrown object. Class type exceptions are probably better than fundamentals simply because they can contain more information about the reason for the exception.

In using a class or class hierarchy there are a couple of points you should consider:

  1. Both the copy constructor and destructor of the exception object must never throw an exception. If they do you're program will terminate immediately.(ISO 15.5/1)

  2. If your exception objects have base classes, then use public inheritance.
    A handler will only be selected for a derived to base class if the base class is accessible.(ISO 15.3/3)

  3. Finally, (for all exception types) ensure that the expression being thrown cannot itself result in an exception being thrown.

For example:

class Ex {
public:
  Ex(int i) 
  : m_i (i)
  {
    if (i > 10) {
      throw "Exception value out of range";
    }
  }

  int m_i;
};


void foo (bool b) {
  if (! b) {
     // 'b' is false this is bad - throw an exception
     throw Ex(20);    // Ooops - throw's a string, not an Ex
  }
}
answered 2009-02-17T11:29:27.397
0

For a current project, we thought about the appropriate action that could be taken by the main program loop. The basic program accepts XML messages, and saves the information into a database (with a fair amount of processing in between).

  1. Data errors that indicate something wrong the input. Appropriate action is to save the message to a log directory but not process it.
  2. Infrastructure errors that indicate some subcomponent (like the input queue, an SQL database, a JNI library) is malfunctioning. Sleep for a few minutes then reconnect.
  3. Configuration errors that indicate some aspect configuration is unworkable. Exit the program.

The first item is a checked exception, since we considered data checking to be part of a method's interface. The others are unchecked since the main loop cannot know the implementations of subcomponents, e.g. an implementation may use an SQL database, or may simply persist data in memory -- the caller doesn't need to know.

answered 2009-02-17T10:52:51.477
0

From the C++ FAQ, [17.12] What should I throw?:

Generally, it's best to throw objects, not built-ins. If possible, you should throw instances of classes that derive (ultimately) from the std::exception class.

...and

The most common practice is to throw a temporary: (see example that follows)

answered 2013-02-04T16:02:02.680

Your Answer