How to throw std::exceptions with variable messages?
Solution 1:
The standard exceptions can be constructed from a std::string
:
#include <stdexcept>
char const * configfile = "hardcode.cfg";
std::string const anotherfile = get_file();
throw std::runtime_error(std::string("Failed: ") + configfile);
throw std::runtime_error("Error: " + anotherfile);
Note that the base class std::exception
can not be constructed thus; you have to use one of the concrete, derived classes.
Solution 2:
Here is my solution:
#include <stdexcept>
#include <sstream>
class Formatter
{
public:
Formatter() {}
~Formatter() {}
template <typename Type>
Formatter & operator << (const Type & value)
{
stream_ << value;
return *this;
}
std::string str() const { return stream_.str(); }
operator std::string () const { return stream_.str(); }
enum ConvertToString
{
to_str
};
std::string operator >> (ConvertToString) { return stream_.str(); }
private:
std::stringstream stream_;
Formatter(const Formatter &);
Formatter & operator = (Formatter &);
};
Example:
throw std::runtime_error(Formatter() << foo << 13 << ", bar" << myData); // implicitly cast to std::string
throw std::runtime_error(Formatter() << foo << 13 << ", bar" << myData >> Formatter::to_str); // explicitly cast to std::string
Solution 3:
There are different exceptions such as runtime_error
, range_error
, overflow_error
, logic_error
, etc.. You need to pass the string into its constructor, and you can concatenate whatever you want to your message. That's just a string operation.
std::string errorMessage = std::string("Error: on file ")+fileName;
throw std::runtime_error(errorMessage);
You can also use boost::format
like this:
throw std::runtime_error(boost::format("Error processing file %1") % fileName);
Solution 4:
The following class might come quite handy:
struct Error : std::exception
{
char text[1000];
Error(char const* fmt, ...) __attribute__((format(printf,2,3))) {
va_list ap;
va_start(ap, fmt);
vsnprintf(text, sizeof text, fmt, ap);
va_end(ap);
}
char const* what() const throw() { return text; }
};
Usage example:
throw Error("Could not load config file '%s'", configfile.c_str());