diff --git a/src/lib/config/module_spec.cc b/src/lib/config/module_spec.cc index 0defd6d342..a9310708f0 100644 --- a/src/lib/config/module_spec.cc +++ b/src/lib/config/module_spec.cc @@ -40,13 +40,14 @@ check_leaf_item(ConstElementPtr spec, const std::string& name, if (spec->get(name)->getType() == type) { return; } else { - throw ModuleSpecError(name + " not of type " + Element::typeToName(type)); + isc_throw(ModuleSpecError, + name + " not of type " + Element::typeToName(type)); } } else if (mandatory) { // todo: want parent item name, and perhaps some info about location // in list? or just catch and throw new... // or make this part non-throwing and check return value... - throw ModuleSpecError(name + " missing in " + spec->str()); + isc_throw(ModuleSpecError, name + " missing in " + spec->str()); } } @@ -80,7 +81,7 @@ check_config_item(ConstElementPtr spec) { void check_config_item_list(ConstElementPtr spec) { if (spec->getType() != Element::list) { - throw ModuleSpecError("config_data is not a list of elements"); + isc_throw(ModuleSpecError, "config_data is not a list of elements"); } BOOST_FOREACH(ConstElementPtr item, spec->listValue()) { check_config_item(item); @@ -122,7 +123,7 @@ void check_statistics_item_list(ConstElementPtr spec); void check_statistics_item_list(ConstElementPtr spec) { if (spec->getType() != Element::list) { - throw ModuleSpecError("statistics is not a list of elements"); + isc_throw(ModuleSpecError, "statistics is not a list of elements"); } BOOST_FOREACH(ConstElementPtr item, spec->listValue()) { check_config_item(item); @@ -135,7 +136,7 @@ check_statistics_item_list(ConstElementPtr spec) { && item->contains("item_default")) { if(!check_format(item->get("item_default"), item->get("item_format"))) { - throw ModuleSpecError( + isc_throw(ModuleSpecError, "item_default not valid type of item_format"); } } @@ -152,7 +153,7 @@ check_command(ConstElementPtr spec) { void check_command_list(ConstElementPtr spec) { if (spec->getType() != Element::list) { - throw ModuleSpecError("commands is not a list of elements"); + isc_throw(ModuleSpecError, "commands is not a list of elements"); } BOOST_FOREACH(ConstElementPtr item, spec->listValue()) { check_command(item); @@ -183,7 +184,7 @@ check_module_specification(ConstElementPtr def) { try { check_data_specification(def); } catch (const TypeError& te) { - throw ModuleSpecError(te.what()); + isc_throw(ModuleSpecError, te.what()); } } } @@ -314,14 +315,14 @@ moduleSpecFromFile(const std::string& file_name, const bool check) if (!file) { std::stringstream errs; errs << "Error opening " << file_name << ": " << strerror(errno); - throw ModuleSpecError(errs.str()); + isc_throw(ModuleSpecError, errs.str()); } ConstElementPtr module_spec_element = Element::fromJSON(file, file_name); if (module_spec_element->contains("module_spec")) { return (ModuleSpec(module_spec_element->get("module_spec"), check)); } else { - throw ModuleSpecError("No module_spec in specification"); + isc_throw(ModuleSpecError, "No module_spec in specification"); } } @@ -333,7 +334,7 @@ moduleSpecFromFile(std::ifstream& in, const bool check) if (module_spec_element->contains("module_spec")) { return (ModuleSpec(module_spec_element->get("module_spec"), check)); } else { - throw ModuleSpecError("No module_spec in specification"); + isc_throw(ModuleSpecError, "No module_spec in specification"); } } diff --git a/src/lib/config/module_spec.h b/src/lib/config/module_spec.h index ce3762f203..27dcfe38b8 100644 --- a/src/lib/config/module_spec.h +++ b/src/lib/config/module_spec.h @@ -26,15 +26,11 @@ namespace isc { namespace config { /// A standard ModuleSpec exception that is thrown when a /// specification is not in the correct form. /// - /// TODO: use jinmei's exception class as a base and not c_str in - /// what() there - class ModuleSpecError : public std::exception { + class ModuleSpecError : public isc::Exception { public: - ModuleSpecError(std::string m = "Module specification is invalid") : msg(m) {} - ~ModuleSpecError() throw() {} - const char* what() const throw() { return (msg.c_str()); } - private: - std::string msg; + ModuleSpecError(const char* file, size_t line, + const char* what = "Module specification is invalid") : + isc::Exception(file, line, what) {} }; /// diff --git a/src/lib/exceptions/exceptions.h b/src/lib/exceptions/exceptions.h index b68f3c4615..562cc49ae4 100644 --- a/src/lib/exceptions/exceptions.h +++ b/src/lib/exceptions/exceptions.h @@ -197,6 +197,16 @@ public: throw type(__FILE__, __LINE__, oss__.str().c_str(), param1); \ } while (1) +/// +/// Similar as isc_throw, but allows the exception to have two additional +/// parameters (the stream/text goes first) +#define isc_throw_2(type, stream, param1, param2) \ + do { \ + std::ostringstream oss__; \ + oss__ << stream; \ + throw type(__FILE__, __LINE__, oss__.str().c_str(), param1, param2); \ + } while (1) + } #endif // __EXCEPTIONS_H diff --git a/src/lib/log/compiler/Makefile.am b/src/lib/log/compiler/Makefile.am index 1f47ba9158..84cd4f6e28 100644 --- a/src/lib/log/compiler/Makefile.am +++ b/src/lib/log/compiler/Makefile.am @@ -16,3 +16,4 @@ noinst_PROGRAMS = message message_SOURCES = message.cc message_LDADD = $(top_builddir)/src/lib/log/liblog.la message_LDADD += $(top_builddir)/src/lib/util/libutil.la +message_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la diff --git a/src/lib/log/compiler/message.cc b/src/lib/log/compiler/message.cc index fb0f038597..bb10481580 100644 --- a/src/lib/log/compiler/message.cc +++ b/src/lib/log/compiler/message.cc @@ -25,6 +25,8 @@ #include #include +#include + #include #include @@ -325,8 +327,8 @@ writeHeaderFile(const string& file, const vector& ns_components, ofstream hfile(header_file.fullName().c_str()); if (hfile.fail()) { - throw MessageException(LOG_OPEN_OUTPUT_FAIL, header_file.fullName(), - strerror(errno)); + isc_throw_2(MessageException, LOG_OPEN_OUTPUT_FAIL, + header_file.fullName(), strerror(errno)); } // Write the header preamble. If there is an error, we'll pick it up @@ -359,8 +361,8 @@ writeHeaderFile(const string& file, const vector& ns_components, // Report errors (if any) and exit if (hfile.fail()) { - throw MessageException(LOG_WRITE_ERROR, header_file.fullName(), - strerror(errno)); + isc_throw_2(MessageException, LOG_WRITE_ERROR, header_file.fullName(), + strerror(errno)); } hfile.close(); @@ -425,8 +427,8 @@ writeProgramFile(const string& file, const vector& ns_components, ofstream ccfile(program_file.fullName().c_str()); if (ccfile.fail()) { - throw MessageException(LOG_OPEN_OUTPUT_FAIL, program_file.fullName(), - strerror(errno)); + isc_throw_2(MessageException, LOG_OPEN_OUTPUT_FAIL, + program_file.fullName(), strerror(errno)); } // Write the preamble. If there is an error, we'll pick it up after @@ -483,8 +485,8 @@ writeProgramFile(const string& file, const vector& ns_components, // Report errors (if any) and exit if (ccfile.fail()) { - throw MessageException(LOG_WRITE_ERROR, program_file.fullName(), - strerror(errno)); + isc_throw_2(MessageException, LOG_WRITE_ERROR, program_file.fullName(), + strerror(errno)); } ccfile.close(); diff --git a/src/lib/log/message_exception.h b/src/lib/log/message_exception.h index eebee89ffd..bc4c3d8b34 100644 --- a/src/lib/log/message_exception.h +++ b/src/lib/log/message_exception.h @@ -15,12 +15,14 @@ #ifndef __MESSAGE_EXCEPTION_H #define __MESSAGE_EXCEPTION_H +#include +#include + #include #include #include #include -#include namespace isc { namespace log { @@ -31,14 +33,16 @@ namespace log { /// code and its arguments to be encapsulated in an exception and thrown /// up the stack. -class MessageException : public std::exception { +class MessageException : public isc::Exception { public: /// \brief Constructor /// /// \param id Message identification. /// \param lineno Line number on which error occurred (if > 0). - MessageException(MessageID id, int lineno = 0) : id_(id) + MessageException(const char* file, size_t line, + MessageID id, int lineno = 0) + : isc::Exception(file, line, ""), id_(id) { if (lineno > 0) { args_.push_back(boost::lexical_cast(lineno)); @@ -50,8 +54,9 @@ public: /// \param id Message identification. /// \param arg1 First message argument. /// \param lineno Line number on which error occurred (if > 0). - MessageException(MessageID id, const std::string& arg1, int lineno = 0) - : id_(id) + MessageException(const char* file, size_t line, + MessageID id, const std::string& arg1, int lineno = 0) + : isc::Exception(file, line, ""), id_(id) { if (lineno > 0) { args_.push_back(boost::lexical_cast(lineno)); @@ -65,8 +70,10 @@ public: /// \param arg1 First message argument. /// \param arg2 Second message argument. /// \param lineno Line number on which error occurred (if > 0). - MessageException(MessageID id, const std::string& arg1, - const std::string& arg2, int lineno = 0) : id_(id) + MessageException(const char* file, size_t line, + MessageID id, const std::string& arg1, + const std::string& arg2, int lineno = 0) + : isc::Exception(file, line, ""), id_(id) { if (lineno > 0) { args_.push_back(boost::lexical_cast(lineno)); diff --git a/src/lib/log/message_reader.cc b/src/lib/log/message_reader.cc index 2710ab87a3..700d5c678d 100644 --- a/src/lib/log/message_reader.cc +++ b/src/lib/log/message_reader.cc @@ -48,7 +48,8 @@ MessageReader::readFile(const string& file, MessageReader::Mode mode) { // Open the file. ifstream infile(file.c_str()); if (infile.fail()) { - throw MessageException(LOG_INPUT_OPEN_FAIL, file, strerror(errno)); + isc_throw_2(MessageException, LOG_INPUT_OPEN_FAIL, file, + strerror(errno)); } // Loop round reading it. As we process the file one line at a time, @@ -65,7 +66,7 @@ MessageReader::readFile(const string& file, MessageReader::Mode mode) { // Why did the loop terminate? if (!infile.eof()) { - throw MessageException(LOG_READ_ERROR, file, strerror(errno)); + isc_throw_2(MessageException, LOG_READ_ERROR, file, strerror(errno)); } infile.close(); } @@ -114,7 +115,8 @@ MessageReader::parseDirective(const std::string& text) { } else { // Unrecognised directive - throw MessageException(LOG_UNRECOGNISED_DIRECTIVE, tokens[0], lineno_); + isc_throw_2(MessageException, LOG_UNRECOGNISED_DIRECTIVE, tokens[0], + lineno_); } } @@ -138,13 +140,14 @@ MessageReader::parsePrefix(const vector& tokens) { // and numeric characters (and underscores) and does not start with a // digit. if (invalidSymbol(prefix_)) { - throw MessageException(LOG_PREFIX_INVALID_ARG, prefix_, lineno_); + isc_throw_2(MessageException, LOG_PREFIX_INVALID_ARG, prefix_, + lineno_); } } else { // Too many arguments - throw MessageException(LOG_PREFIX_EXTRA_ARGS, lineno_); + isc_throw_1(MessageException, LOG_PREFIX_EXTRA_ARGS, lineno_); } } @@ -172,10 +175,10 @@ MessageReader::parseNamespace(const vector& tokens) { // Check argument count if (tokens.size() < 2) { - throw MessageException(LOG_NAMESPACE_NO_ARGS, lineno_); + isc_throw_1(MessageException, LOG_NAMESPACE_NO_ARGS, lineno_); } else if (tokens.size() > 2) { - throw MessageException(LOG_NAMESPACE_EXTRA_ARGS, lineno_); + isc_throw_1(MessageException, LOG_NAMESPACE_EXTRA_ARGS, lineno_); } @@ -187,12 +190,13 @@ MessageReader::parseNamespace(const vector& tokens) { "abcdefghijklmnopqrstuvwxyz" "0123456789_:"; if (tokens[1].find_first_not_of(valid_chars) != string::npos) { - throw MessageException(LOG_NAMESPACE_INVALID_ARG, tokens[1], lineno_); + isc_throw_2(MessageException, LOG_NAMESPACE_INVALID_ARG, tokens[1], + lineno_); } // All OK - unless the namespace has already been set. if (ns_.size() != 0) { - throw MessageException(LOG_DUPLICATE_NAMESPACE, lineno_); + isc_throw_1(MessageException, LOG_DUPLICATE_NAMESPACE, lineno_); } // Prefix has not been set, so set it and return success. @@ -219,7 +223,7 @@ MessageReader::parseMessage(const std::string& text, MessageReader::Mode mode) { // A line comprising just the message introducer is not valid. if (text.size() == 1) { - throw MessageException(LOG_NO_MESSAGE_ID, text, lineno_); + isc_throw_2(MessageException, LOG_NO_MESSAGE_ID, text, lineno_); } // Strip off the introducer and any leading space after that. @@ -230,7 +234,8 @@ MessageReader::parseMessage(const std::string& text, MessageReader::Mode mode) { if (first_delim == string::npos) { // Just a single token in the line - this is not valid - throw MessageException(LOG_NO_MESSAGE_TEXT, message_line, lineno_); + isc_throw_2(MessageException, LOG_NO_MESSAGE_TEXT, message_line, + lineno_); } // Extract the first token into the message ID, preceding it with the @@ -240,7 +245,8 @@ MessageReader::parseMessage(const std::string& text, MessageReader::Mode mode) { string ident = prefix_ + message_line.substr(0, first_delim); if (prefix_.empty()) { if (invalidSymbol(ident)) { - throw MessageException(LOG_INVALID_MESSAGE_ID, ident, lineno_); + isc_throw_2(MessageException, LOG_INVALID_MESSAGE_ID, ident, + lineno_); } } isc::util::str::uppercase(ident); @@ -252,7 +258,8 @@ MessageReader::parseMessage(const std::string& text, MessageReader::Mode mode) { // ?? This happens if there are trailing delimiters, which should not // occur as we have stripped trailing spaces off the line. Just treat // this as a single-token error for simplicity's sake. - throw MessageException(LOG_NO_MESSAGE_TEXT, message_line, lineno_); + isc_throw_2(MessageException, LOG_NO_MESSAGE_TEXT, message_line, + lineno_); } // Add the result to the dictionary and to the non-added list if the add to