Browse Source

[2572] convert OpenError to Unexpected in the stream ver. of pushSource.

with the change for #2572 this version can now have this exception, and
since it's intended to be hidden within the lexer and input source classes,
we need to convert it.  doc/tests are also added/updated.
JINMEI Tatuya 12 years ago
parent
commit
f45c804082

+ 7 - 1
src/lib/dns/master_lexer.cc

@@ -144,7 +144,13 @@ MasterLexer::pushSource(const char* filename, std::string* error) {
 
 void
 MasterLexer::pushSource(std::istream& input) {
-    impl_->sources_.push_back(InputSourcePtr(new InputSource(input)));
+    try {
+        impl_->sources_.push_back(InputSourcePtr(new InputSource(input)));
+    } catch (const InputSource::OpenError& ex) {
+        // Convert the "internal" exception to public one.
+        isc_throw(Unexpected, "Failed to push a stream to lexer: " <<
+                  ex.what());
+    }
     impl_->source_ = impl_->sources_.back().get();
     impl_->has_previous_ = false;
     impl_->last_was_eol_ = true;

+ 16 - 0
src/lib/dns/master_lexer.h

@@ -401,6 +401,22 @@ public:
     /// The behavior of the lexer is undefined if the caller builds or adds
     /// data in \c input after pushing it.
     ///
+    /// Except for rare case system errors such as memory allocation failure,
+    /// this method is generally expected to be exception free.  However,
+    /// it can still throw if it encounters an unexpected failure when it
+    /// tries to identify the "size" of the input source (see
+    /// \c getTotalSourceSize()).  It's an unexpected result unless the
+    /// caller intentionally passes a broken stream; otherwise it would mean
+    /// some system-dependent unexpected behavior or possibly an internal bug.
+    /// In these cases it throws an \c Unexpected exception.  Note that
+    /// this version of the method doesn't return a boolean unlike the
+    /// other version that takes a file name; since this failure is really
+    /// unexpected and can be critical, it doesn't make sense to give the
+    /// caller an option to continue (other than by explicitly catching the
+    /// exception).
+    ///
+    /// \throw Unexpected An unexpected failure happens in initialization.
+    ///
     /// \param input An input stream object that produces textual
     /// representation of DNS RRs.
     void pushSource(std::istream& input);

+ 9 - 0
src/lib/dns/tests/master_lexer_unittest.cc

@@ -80,6 +80,15 @@ TEST_F(MasterLexerTest, pushStream) {
     checkEmptySource(lexer);
 }
 
+TEST_F(MasterLexerTest, pushStreamFail) {
+    // Pretend a "bad" thing happened in the stream.  This will make the
+    // initialization throw an exception.
+    ss << "test";
+    ss.setstate(std::ios_base::badbit);
+
+    EXPECT_THROW(lexer.pushSource(ss), isc::Unexpected);
+}
+
 TEST_F(MasterLexerTest, pushFile) {
     // We use zone file (-like) data, but in this test that actually doesn't
     // matter.