config_parser: Add support for checking file existence

This will be used to reduce the number of config parser errors printed
to the logs.

Change-Id: Ia0337da386bc5dbe32c04bf2c3264997a9ad6da1
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/config_parser.cpp b/src/config_parser.cpp
index 74a47ba..25c4d11 100644
--- a/src/config_parser.cpp
+++ b/src/config_parser.cpp
@@ -252,6 +252,7 @@
 {
     Parse parse(filename);
 
+    bool fileExists = true;
     try
     {
         auto fd = stdplus::fd::open(filename.c_str(),
@@ -265,14 +266,16 @@
     catch (const stdplus::exception::Eof&)
     {
     }
-    catch (const std::exception& e)
+    catch (const std::system_error& e)
     {
+        fileExists = false;
         // TODO: Pass exceptions once callers can handle them
         parse.warnings.emplace_back(
-            fmt::format("{}: Read error: {}", filename.native(), e.what()));
+            fmt::format("{}: Open error: {}", filename.native(), e.what()));
     }
 
     this->map = std::move(parse.map);
+    this->fileExists = fileExists;
     this->filename = filename;
     this->warnings = std::move(parse.warnings);
 }
diff --git a/src/config_parser.hpp b/src/config_parser.hpp
index 5d98f52..5df8d98 100644
--- a/src/config_parser.hpp
+++ b/src/config_parser.hpp
@@ -168,6 +168,12 @@
      */
     Parser(const fs::path& filename);
 
+    /** @brief Determine if the loaded file exists */
+    inline bool getFileExists() const noexcept
+    {
+        return fileExists;
+    }
+
     /** @brief Determine if there were warnings parsing the file
      *  @return The number of parsing issues in the file
      */
@@ -194,6 +200,7 @@
     void writeFile(const fs::path& filename);
 
   private:
+    bool fileExists = false;
     fs::path filename;
     std::vector<std::string> warnings;
 };
diff --git a/test/test_config_parser.cpp b/test/test_config_parser.cpp
index 3bb0897..e742cdf 100644
--- a/test/test_config_parser.cpp
+++ b/test/test_config_parser.cpp
@@ -112,6 +112,7 @@
 
 TEST_F(TestConfigParser, EmptyObject)
 {
+    EXPECT_FALSE(parser.getFileExists());
     EXPECT_TRUE(parser.getFilename().empty());
     EXPECT_EQ(0, parser.getWarnings().size());
     EXPECT_EQ(SectionMap(), parser.map);
@@ -120,6 +121,7 @@
 TEST_F(TestConfigParser, ReadDirectory)
 {
     parser.setFile("/");
+    EXPECT_FALSE(parser.getFileExists());
     EXPECT_EQ("/", parser.getFilename());
     EXPECT_EQ(1, parser.getWarnings().size());
     EXPECT_EQ(SectionMap(), parser.map);
@@ -128,6 +130,7 @@
 TEST_F(TestConfigParser, ReadConfigDataMissingFile)
 {
     parser.setFile("/no-such-path");
+    EXPECT_FALSE(parser.getFileExists());
     EXPECT_EQ("/no-such-path", parser.getFilename());
     EXPECT_EQ(1, parser.getWarnings().size());
     EXPECT_EQ(SectionMap(), parser.map);
@@ -137,6 +140,7 @@
 {
     WriteSampleFile();
     parser.setFile(filename);
+    EXPECT_TRUE(parser.getFileExists());
     EXPECT_EQ(filename, parser.getFilename());
     EXPECT_EQ(4, parser.getWarnings().size());
     ValidateSectionMap();