tags:

views:

304

answers:

7

I am writing some new code that will throw a custom exception - I want to include an error string and a status code. Which class should be exception derive from? std::exception? std::runtime_error? Any other 'gotchas' to worry about? I'm thinking of something like the following:

class MyException : public std::exception(?)
{
public:
    enum Status
    {
        ERROR_FOO,
        ERROR_BAR,
        ...
    };

    MyException(const std::string& error, Status code) :
        error_(error), code_(code)
    {
        ...
    }

    virtual const char* what() const
    {
        return error_.c_str();
    }

    Status code() const
    {
        return code_;
    }
private:
    std::string error_;
    Status code_;
};

Then in the code:

throw MyException("Ooops!", MyException::ERROR_BAR);
+6  A: 

Consider whether the status code is really appropriate. It's usually superior to create a hierarchy of exception classes. This way, the caller can better control which exceptions to treat and how and it makes the interface simpler.

Of course, sometimes status codes are still appropriate (compilers use them all the time).

Konrad Rudolph
In this case there will be many different status codes, but +1 for a good point nonetheless.
Rob
A: 

check this link. http://www.codeguru.com/forum/archive/index.php/t-375766.html

yesraaj
+3  A: 

You can use any standard exception type as a base, but it will really help the users of the class (including yourself) if you pick the right one:

  • If the error is something that could have been avoided, had the user been more careful or precise, then use logic_error.
  • If it's something coming from the system that the user couldn't have prevented, use runtime_error.

Of course, you could also use one of the other standard derived exceptions (e.g. invalid_argument, range_error, bad_cast) if it better describes the error.

efotinis
+2  A: 

Your exception class is not exception safe. If copy constructor of std::string throw exception, program will be terminated.

class MyException : public std::exception
{
public:
    enum Status
    {
        ERROR_FOO,
        ERROR_BAR,
        ...
    };

    MyException(const char* error, Status code) :
        std::exception(error),
        code_(code)
    {
        ...
    }
    ...
private:
    Status code_;
};
Lazin
+1  A: 

An extremely helpful resource in that regard is Marshall Cline's C++ FAQ LITE. He has a chapter on exceptions and error handling which might be useful to you.

mookid8000
+8  A: 

Boost has a great document on error and exception handling which talks about common gotchas and how to properly inherit from std::exception(s).

David Holm
Perfect! Thanks.
Rob
+1 from me too. Nice article.
efotinis
A: 

Both the destructor and what() methods should be marked no throw.
In MS-Studio it ignores the throw qualifier and compiles fine, but for compliance with the standard and portability you should add it to your code.

// What is a no throw operation.
virtual const char* what() const throw ()
{
    return error_.c_str();
}

Other comments:

I would not inherit directly from exception.
Look at the standard exceptions derived from exception and see if any fit the bill.

Rather than use an error code. You could use a hierarchy of exception types. This makes it easier to catch.

class MyException: public std::runtime_error
{  // STUFF  .. Put all the error message stuff here
};

class MyFOO_Exception: public MyException
{  // STUFF
};

class MyBAR_Exception: public MyException
{  // STUFF
}
Martin York