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?
}
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.
RuntimeException, it's an unchecked exception so you don't have to catch it.
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 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With