Throwing my own exceptions

I am writing some new code that will throw a custom exception - I want to include an error line and a status code. What class should the exception be thrown from? std::exception

? std::runtime_error

? Any other "bugs" to worry about? I am 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 code:

throw MyException("Ooops!", MyException::ERROR_BAR);

      

+1


source to share


6 answers


Boost has an excellent document on error and exception that talks about common errors and how to properly inherit from std :: exception (s).



+8


source


Consider whether the status code is actually appropriate. It usually trumps the exception class hierarchy. This way the caller can better control which exceptions to handle and how, and this simplifies the interface.



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

+6


source


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

  • If an error is something that could have been avoided if the user were more careful or precise, use logic_error .
  • If this happens from a system that the user was unable to prevent, use runtime_error .

Of course, you can also use one of the other standard derived exceptions (for example invalid_argument, range_error, bad_cast

) if it better describes the error.

+3


source


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

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_;
};

      

+2


source


A very useful resource in this regard is the Marshall Cline C ++ FAQ LITE . He has a chapter on exceptions and error handling that you might find useful.

+1


source


Both the destructor and what () methods must be flagged without being cast.
In MS-Studio, it ignores the throw qualifier and compiles just fine, but for standard compliance and portability, you must 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 an exception.
Take a look at the standard exceptions generated from the exception and see if any account fits.

Instead of using an error code. You can 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
}

      

0


source







All Articles