Here’s a short but handy C++ Snippet. I was looking for a way to quickly generate runtime exceptions with useful information about the current program state. My process was:
- Create a string stream
- Build the message
- Throw the exception using the string from the stream
I felt like this was particularly cumbersome and quite annoying, especially for doing things like string parsing or SQL because there are a lot of places in the code where error checking is required.
In any case, I came up with this simple little class tempate which sits in a single header file and is included in the cpp file where it is to be used.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #ifndef _UTILITY_EXCEPTIONSTREAM_H_ #define _UTILITY_EXCEPTIONSTREAM_H_ #include <exception> #include <sstream> namespace utility { /// used to simplify the process of generating an exception message /** * Derives from stringstream so provides an ostream interface, but throws * an exception with the contents of the string when the object is destroyed * * \tparam Exception_t must be an exception type which accepts a * const char* in it's constructor * */ template <typename Exception_t> class ExceptionStream : public std::stringstream { public: ~ExceptionStream() { throw Exception_t( str().c_str() ); } std::ostream& operator()() { return *this; } }; typedef ExceptionStream<std::runtime_error> ex; } /* namespace utility */ #endif /* EXCEPTIONSTREAM_H_ */ |
Usage is like this:
1 2 3 4 5 6 7 8 9 10 | ex fExp; fExp = evalf( m_expression["radius"].subs(m_x == iRadius)); if( is_a<numeric>(fExp) ) radius= ex_to<numeric>(fExp).to_double(); else { utility::ex()() << "GiNaC failed to parse radius expression: " << fExp; } |
Here I’m using GiNaC to parse a string into a mathematical expression. If the process fails I want to throw a runtime exception (typedef’ed as utility::ex).
The class derives from string stream so it works just like a string stream… building a string by catting together the RHS of all the string operators. The magic is that the destructor for the class throws an exception. The message for the exception is the string that was built.
It’s a very handy time saver… though I’m not sure if it’s actually safe to use. If the destructor throws an exception, is the object memory still freed?
#1 by MCM on September 11, 2012 - 5:02 pm
Throwing in an destructor is generally considered bad. One obvious reason is, that many compilers produce code that abort()s if another exception happens during the handling of a first one. See http://stackoverflow.com/questions/130117/throwing-exceptions-out-of-a-destructor for more on this.
#2 by mcg on October 4, 2013 - 1:42 pm
I came here looking for a solution like this, thanks! I think MCM’s suggestion is well formed. But I think I have a simpler solution: what if ExceptionStream were just a derived class of Exception_t, and contains an stringstream object? Then override the what() function to return the stringstream’s c_str() output.