Browse Source

[trac1025] Handle possible bad_lexical_cast exception in Formatter::arg()

Stephen Morris 14 years ago
parent
commit
7c7238ca55
2 changed files with 33 additions and 1 deletions
  1. 31 1
      src/lib/log/log_formatter.h
  2. 2 0
      src/lib/log/tests/Makefile.am

+ 31 - 1
src/lib/log/log_formatter.h

@@ -18,12 +18,28 @@
 #include <cstddef>
 #include <string>
 #include <iostream>
+
+#include <exceptions/exceptions.h>
 #include <boost/lexical_cast.hpp>
 #include <log/logger_level.h>
 
 namespace isc {
 namespace log {
 
+/// \brief Format Failure
+///
+/// This exception is used to wrap a bad_lexical_cast exception thrown during
+/// formatting an argument.
+
+class FormatFailure : public isc::Exception {
+public:
+    FormatFailure(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what)
+    {}
+};
+
+
+///
 /// \brief The internal replacement routine
 ///
 /// This is used internally by the Formatter. Replaces a placeholder
@@ -156,7 +172,21 @@ public:
     /// \param arg The argument to place into the placeholder.
     template<class Arg> Formatter& arg(const Arg& value) {
         if (logger_) {
-            return (arg(boost::lexical_cast<std::string>(value)));
+            try {
+                return (arg(boost::lexical_cast<std::string>(value)));
+            } catch (const boost::bad_lexical_cast& ex) {
+
+                // A bad_lexical_cast during a conversion to a string is
+                // *extremely* unlikely to fail.  However, there is nothing
+                // in the documentation that rules it out, so we need to handle
+                // it.  As it is a potentially very serious problem, throw the
+                // exception detailing the problem with as much information as
+                // we can.  (Note that this does not include 'value' -
+                // boost::lexical_cast failed to convert it to a string, so an
+                // attempt to do so here would probably fail as well.)
+                isc_throw(FormatFailure, "bad_lexical_cast in call to "
+                          "Formatter::arg(): " << ex.what());
+            }
         } else {
             return (*this);
         }

+ 2 - 0
src/lib/log/tests/Makefile.am

@@ -51,6 +51,7 @@ logger_example_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 logger_example_LDFLAGS = $(AM_LDFLAGS) $(LOG4CPLUS_LDFLAGS)
 logger_example_LDADD  = $(top_builddir)/src/lib/log/liblog.la
 logger_example_LDADD += $(top_builddir)/src/lib/util/libutil.la
+logger_example_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 
 check_PROGRAMS += init_logger_test
 init_logger_test_SOURCES = init_logger_test.cc
@@ -58,6 +59,7 @@ init_logger_test_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 init_logger_test_LDFLAGS = $(AM_LDFLAGS) $(LOG4CPLUS_LDFLAGS)
 init_logger_test_LDADD  = $(top_builddir)/src/lib/log/liblog.la
 init_logger_test_LDADD += $(top_builddir)/src/lib/util/libutil.la
+init_logger_test_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 
 noinst_PROGRAMS = $(TESTS)