Print error message if cannot open `.blazerc` file
PiperOrigin-RevId: 474406363
Change-Id: Ice887df811751a6840b9f30465ee6db3ffdd2208
diff --git a/src/main/cpp/rc_file.cc b/src/main/cpp/rc_file.cc
index 266cc13..912bfa4 100644
--- a/src/main/cpp/rc_file.cc
+++ b/src/main/cpp/rc_file.cc
@@ -55,9 +55,11 @@
string* error_text) {
BAZEL_LOG(INFO) << "Parsing the RcFile " << filename;
string contents;
- if (!blaze_util::ReadFile(filename, &contents)) {
+ string error_message;
+ if (!blaze_util::ReadFile(filename, &contents, &error_message)) {
blaze_util::StringPrintf(error_text,
- "Unexpected error reading .blazerc file '%s'", filename.c_str());
+ "Unexpected error reading .blazerc file '%s': %s",
+ filename.c_str(), error_message.c_str());
return ParseError::UNREADABLE_FILE;
}
const std::string canonical_filename =
diff --git a/src/main/cpp/util/file_platform.h b/src/main/cpp/util/file_platform.h
index 4e8e254..a0860de 100644
--- a/src/main/cpp/util/file_platform.h
+++ b/src/main/cpp/util/file_platform.h
@@ -90,8 +90,12 @@
// Replaces 'content' with contents of file 'filename'.
// If `max_size` is positive, the method reads at most that many bytes;
// otherwise the method reads the whole file.
+// If fails to read content from the file, `error_message` can provide extra
+// information about the failure.
// Returns false on error. Can be called from a signal handler.
bool ReadFile(const std::string &filename, std::string *content,
+ std::string *error_message, int max_size = 0);
+bool ReadFile(const std::string &filename, std::string *content,
int max_size = 0);
bool ReadFile(const Path &path, std::string *content, int max_size = 0);
diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc
index d89c34f..8b1d541 100644
--- a/src/main/cpp/util/file_posix.cc
+++ b/src/main/cpp/util/file_posix.cc
@@ -265,16 +265,27 @@
return result;
}
-bool ReadFile(const string &filename, string *content, int max_size) {
+bool ReadFile(const string &filename, string *content, string *error_message,
+ int max_size) {
int fd = open(filename.c_str(), O_RDONLY);
- if (fd == -1) return false;
+ if (fd == -1) {
+ if (error_message != nullptr) {
+ *error_message = blaze_util::GetLastErrorString();
+ }
+ return false;
+ }
bool result = ReadFrom(fd, content, max_size);
close(fd);
return result;
}
+bool ReadFile(const string &filename, string *content, int max_size) {
+ return ReadFile(filename, content, /* error_message= */nullptr, max_size);
+}
+
bool ReadFile(const Path &path, std::string *content, int max_size) {
- return ReadFile(path.AsNativePath(), content, max_size);
+ return ReadFile(
+ path.AsNativePath(), content, /* error_message= */nullptr, max_size);
}
bool ReadFile(const string &filename, void *data, size_t size) {
diff --git a/src/main/cpp/util/file_windows.cc b/src/main/cpp/util/file_windows.cc
index 5798ffa..e49a1a8 100644
--- a/src/main/cpp/util/file_windows.cc
+++ b/src/main/cpp/util/file_windows.cc
@@ -254,6 +254,11 @@
}
bool ReadFile(const string& filename, string* content, int max_size) {
+ return ReadFile(filename, content, nullptr, max_size);
+}
+
+bool ReadFile(const string& filename, string* content, string* error_message,
+ int max_size) {
if (IsDevNull(filename.c_str())) {
// mimic read(2) behavior: we can always read 0 bytes from /dev/null
content->clear();
@@ -265,8 +270,11 @@
std::string errorText;
Path path = Path(filename, &errorText);
if (!errorText.empty()) {
- BAZEL_LOG(WARNING) << "Path is not valid: " << filename << " :"
- << errorText;
+ std::string message = "Path is not valid: " + filename + " :" + errorText;
+ BAZEL_LOG(WARNING) << message;
+ if (error_message != nullptr) {
+ *error_message = std::move(message);
+ }
return false;
}
return ReadFile(path, content, max_size);
diff --git a/src/test/cpp/rc_options_test.cc b/src/test/cpp/rc_options_test.cc
index 354ed87..44bf26e 100644
--- a/src/test/cpp/rc_options_test.cc
+++ b/src/test/cpp/rc_options_test.cc
@@ -31,6 +31,12 @@
using std::vector;
using ::testing::MatchesRegex;
+#if _WIN32
+constexpr bool kIsWindows = true;
+#else
+constexpr bool kIsWindows = false;
+#endif
+
class RcOptionsTest : public ::testing::Test {
protected:
RcOptionsTest()
@@ -400,8 +406,10 @@
EXPECT_EQ(error, RcFile::ParseError::UNREADABLE_FILE);
ASSERT_THAT(
error_text,
- MatchesRegex(
- "Unexpected error reading .blazerc file '.*not_a_file.bazelrc'"));
+ MatchesRegex(kIsWindows
+ ? "Unexpected error reading \\.blazerc file '.*not_a_file\\.bazelrc':.*"
+ : "Unexpected error reading \\.blazerc file '.*not_a_file\\.bazelrc': "
+ "\\(error: 2\\): No such file or directory"));
}
TEST_F(RcOptionsTest, ImportedFileDoesNotExist) {
@@ -413,7 +421,14 @@
std::unique_ptr<RcFile> rc =
Parse("import_fake_file.bazelrc", &error, &error_text);
EXPECT_EQ(error, RcFile::ParseError::UNREADABLE_FILE);
- ASSERT_EQ(error_text, "Unexpected error reading .blazerc file 'somefile'");
+ if (kIsWindows) {
+ ASSERT_THAT(error_text, MatchesRegex(
+ "Unexpected error reading \\.blazerc file 'somefile':.*"));
+ } else {
+ ASSERT_EQ(error_text,
+ "Unexpected error reading .blazerc file 'somefile': (error: 2): No such "
+ "file or directory");
+ }
}
TEST_F(RcOptionsTest, TryImportedFileDoesNotExist) {