Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I catch this exception?

Tags:

c++

I want to create a number of exception types which derive from std::runtime_error and I want them to have stringstream type functionality. I've therefore created an exception class which composes a std::stringstream and which derives from std::runtime_error:

template<typename T>
class error_stream : public std::runtime_error
{
public:
      error_stream() :
      std::runtime_error(""), ss(std::make_shared<std::basic_stringstream<T>> ())
      {
      }

      ~error_stream() throw()
      {
      }

      template <typename T>
      error_stream & operator << (const T & t)
      {
          *ss << t;
          return *this;
      }

      virtual const char * what() const throw()
      {
          get_str(s_, ss->str());
          return s_.c_str();
      }

protected:

    template <typename T>
    void get_str(std::basic_string<char> & s_, const std::basic_string<T> & str) const
    {
        s_ = str;
    }

    template<>
    void get_str(std::basic_string<char> & s_, const std::basic_string<wchar_t> & str) const
    {
        std::basic_string<char> ret(str.begin(), str.end());
        s_ = ret;
    }

protected:
    std::shared_ptr<std::basic_stringstream<T>> ss;
    mutable std::basic_string<char> s_;
};

And I've created a more specific exception type which in turn derives from this error_stream exception:

template<typename T>
class w32file_exception : public w32utils::error_stream<T> 
{
public:
    w32file_exception() : error_stream<T>() {}
};

However, I've encountered something I don't understand here, because when I throw a w32file_exception I actually can only catch it as it's parent error_stream. Can anyone see what I'm doing wrong?

    try
    {
        throw w32file_exception<char>() << "test";
    }
    catch ( w32file_exception<char> & e )
    {
        ASSERT_PASSED;
    }
    catch ( error_stream<char> & e )
    {
        std::cout << e.what() << std::endl;  // Why do I end up here?
    }
like image 278
Benj Avatar asked May 28 '12 14:05

Benj


People also ask

Which exception Cannot be caught?

Exceptions that Can't be Caught One such exception is the limit exception ( System. LimitException ) that the runtime throws if a governor limit has been exceeded, such as when the maximum number of SOQL queries issued has been exceeded.

Which exception Cannot be caught in Java?

RuntimeException, it's an unchecked exception so you don't have to catch it.

How do I fix exception error in Java?

The try-catch is the simplest method of handling exceptions. Put the code you want to run in the try block, and any Java exceptions that the code throws are caught by one or more catch blocks. This method will catch any type of Java exceptions that get thrown. This is the simplest mechanism for handling exceptions.

What happens if your program does not catch an exception?

What happens if an exception is not caught? If an exception is not caught (with a catch block), the runtime system will abort the program (i.e. crash) and an exception message will print to the console. The message typically includes: name of exception type.


1 Answers

What exactly does your throw look like? Are you using your operator<< before calling throw, like this:

throw w32file_exception<T>() << "fooobar";

Then the answer is, that your operator<< returns an error_stream and no w32file_exception and so the type of the thrown exception is error_stream.

You could solve this problem this way:

template<typename T, typename DERIVED>
    class error_stream : public std::runtime_error
{
public:
    // ...
    template <typename U>
        DERIVED & operator << (const T & t)
    {
        *ss << t;
        return static_cast<DERIVED&>(*this);
    }
    // ...
};

But then you loose the ability to catch every error_stream exception because it is a new Type for every DERIVED type.

like image 145
Florian Sowade Avatar answered Oct 04 '22 12:10

Florian Sowade