Search code examples
c++exceptionstdstring

Exception message empty


I have an exception class as follows:

class FileNotFoundException : public std::exception
{
public:
    FileNotFoundException(const char* message) : errorMessage(message){ }
    const char* what() const throw() override
    {
        return this->errorMessage;
    }
private:
    const char* errorMessage;
};

And I throw this exception like this:

std::string message = "Message";
throw ::FileNotFoundException(message.c_str());

But when I try to handle it using:

try
{
    // the code that throws 
}
catch(::FileNotFoundException& ex)
{
    std::string message = ex.what(); 
}

The string is empty. If anyone can help, I would gladly appreciate it.


Solution

  • You can't just store a pointer to the message. Try either storing it in std::string, or, better, pass it to the parent constructor. Perhaps it's better to inherit from std::runtime_error in that case.

    Here's a complete example:

    #include <iostream>
    #include <string>
    #include <stdexcept>
    
    class FileNotFoundException : public std::runtime_error
    {
    public:
      FileNotFoundException(const char* message) : std::runtime_error(message)
      {
      }
    };
    
    int main()
    {
      try {
        throw ::FileNotFoundException("oops, something happened");
      }
      catch(const ::FileNotFoundException& ex) {
        std::cout << "Exception: '" << ex.what() << "'" << std::endl;
      }
    }
    

    Compiling and running:

    $ g++ -W -Wall --std=gnu++11 a.cpp -oa
    $ ./a
    Exception: 'oops, something happened'
    

    In short (and without details): The class std::exception doesn't have any constructors. It's just a parent class used by all other exceptions. On the other hand, std::runtime_error has a constructor that stores the message for you properly. A complete explanation can be found in Difference: std::runtime_error vs std::exception()

    I think this approach is better than to define what() and using std::string to store the message yourself. That is, if you don't have special needs for the exception class.

    You should also check out the C++ exception hierarchy.