Skip to content

Commit 1492175

Browse files
authored
fix: add GetLastErrorString() helper for accurate OS error messages (#341)
1 parent 95d092e commit 1492175

10 files changed

Lines changed: 81 additions & 57 deletions

File tree

src/ailego/utility/file_helper.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ bool FileHelper::IsSame(const char *path1, const char *path2) {
227227
return (!strcmp(real_path1, real_path2));
228228
}
229229

230+
std::string FileHelper::GetLastErrorString() {
231+
return strerror(errno);
232+
}
233+
230234
#else
231235
#undef RemoveDirectory
232236
#undef DeleteFile
@@ -352,6 +356,25 @@ bool FileHelper::IsSymbolicLink(const char *path) {
352356
(attr & FILE_ATTRIBUTE_REPARSE_POINT));
353357
}
354358

359+
std::string FileHelper::GetLastErrorString() {
360+
DWORD err = GetLastError();
361+
if (err == 0) {
362+
return "No error";
363+
}
364+
char buf[256];
365+
DWORD len = FormatMessageA(
366+
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, err,
367+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, sizeof(buf), nullptr);
368+
if (len > 0) {
369+
// Strip trailing newline that FormatMessage often appends
370+
while (len > 0 && (buf[len - 1] == '\r' || buf[len - 1] == '\n')) {
371+
buf[--len] = '\0';
372+
}
373+
return std::string(buf, len);
374+
}
375+
return "Unknown error " + std::to_string(err);
376+
}
377+
355378
bool FileHelper::IsSame(const char *path1, const char *path2) {
356379
char real_path1[MAX_PATH];
357380
char real_path2[MAX_PATH];

src/core/framework/index_mapping.cc

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
#include <zvec/ailego/io/mmap_file.h>
16+
#include <zvec/ailego/utility/file_helper.h>
1617
#include <zvec/core/framework/index_error.h>
1718
#include <zvec/core/framework/index_logger.h>
1819
#include <zvec/core/framework/index_mapping.h>
@@ -60,7 +61,8 @@ static inline bool WritePadding(ailego::File &file, size_t size) {
6061
static inline int UnpackMappingSize(ailego::File &file, size_t *len) {
6162
IndexFormat::MetaHeader header;
6263
if (file.read(&header, sizeof(header)) != sizeof(header)) {
63-
LOG_ERROR("Failed to read file, errno %d, %s", errno, std::strerror(errno));
64+
LOG_ERROR("Failed to read file, %s",
65+
ailego::FileHelper::GetLastErrorString().c_str());
6466
return IndexError_ReadData;
6567
}
6668

@@ -93,13 +95,8 @@ int IndexMapping::open(const std::string &path, bool cow, bool full_mode) {
9395

9496
bool read_only = copy_on_write_ && !full_mode_;
9597
if (!file_.open(path.c_str(), read_only, false)) {
96-
#if defined(_WIN32) || defined(_WIN64)
97-
LOG_ERROR("Failed to open file %s, win32 error %lu", path.c_str(),
98-
GetLastError());
99-
#else
100-
LOG_ERROR("Failed to open file %s, errno %d, %s", path.c_str(), errno,
101-
std::strerror(errno));
102-
#endif
98+
LOG_ERROR("Failed to open file %s, %s", path.c_str(),
99+
ailego::FileHelper::GetLastErrorString().c_str());
103100
return IndexError_OpenFile;
104101
}
105102

@@ -111,8 +108,8 @@ int IndexMapping::open(const std::string &path, bool cow, bool full_mode) {
111108
}
112109

113110
if (!file_.seek(0, ailego::File::Origin::End)) {
114-
LOG_ERROR("Failed to seek file %s, errno %d, %s", path.c_str(), errno,
115-
std::strerror(errno));
111+
LOG_ERROR("Failed to seek file %s, %s", path.c_str(),
112+
ailego::FileHelper::GetLastErrorString().c_str());
116113
return IndexError_SeekFile;
117114
}
118115
return this->init_index_mapping(mapping_size);
@@ -125,8 +122,8 @@ int IndexMapping::create(const std::string &path, size_t seg_meta_capacity) {
125122

126123
// write() & copying to mmap() will auto extend the file size
127124
if (!file_.create(path.c_str(), 0)) {
128-
LOG_ERROR("Failed to create file %s, errno %d, %s", path.c_str(), errno,
129-
std::strerror(errno));
125+
LOG_ERROR("Failed to create file %s, %s", path.c_str(),
126+
ailego::FileHelper::GetLastErrorString().c_str());
130127
return IndexError_CreateFile;
131128
}
132129
huge_page_ = Ishugetlbfs(path);
@@ -155,22 +152,22 @@ int IndexMapping::init_meta_section() {
155152
// Write index header
156153
IndexFormat::SetupMetaHeader(&meta_header, len - sizeof(meta_footer), len);
157154
if (!file_.seek(current_header_start_offset_, ailego::File::Origin::Begin)) {
158-
LOG_ERROR("Failed to seek file %s, errno %d, %s", path.c_str(), errno,
159-
std::strerror(errno));
155+
LOG_ERROR("Failed to seek file %s, %s", path.c_str(),
156+
ailego::FileHelper::GetLastErrorString().c_str());
160157
return IndexError_SeekFile;
161158
}
162159
if (file_.write(&meta_header, sizeof(meta_header)) != sizeof(meta_header)) {
163-
LOG_ERROR("Failed to write file: %s, errno %d, %s", path.c_str(), errno,
164-
std::strerror(errno));
160+
LOG_ERROR("Failed to write file: %s, %s", path.c_str(),
161+
ailego::FileHelper::GetLastErrorString().c_str());
165162
return IndexError_WriteData;
166163
}
167164

168165
// Write padding data
169166
uint32_t segments_meta_size =
170167
static_cast<uint32_t>(len - (sizeof(meta_header) + sizeof(meta_footer)));
171168
if (!WritePadding(file_, segments_meta_size)) {
172-
LOG_ERROR("Failed to write file: %s, errno %d, %s", path.c_str(), errno,
173-
std::strerror(errno));
169+
LOG_ERROR("Failed to write file: %s, %s", path.c_str(),
170+
ailego::FileHelper::GetLastErrorString().c_str());
174171
return IndexError_WriteData;
175172
}
176173

@@ -180,8 +177,8 @@ int IndexMapping::init_meta_section() {
180177
meta_footer.total_size = len;
181178
IndexFormat::UpdateMetaFooter(&meta_footer, 0);
182179
if (file_.write(&meta_footer, sizeof(meta_footer)) != sizeof(meta_footer)) {
183-
LOG_ERROR("Failed to write file: %s, errno %d, %s", path.c_str(), errno,
184-
std::strerror(errno));
180+
LOG_ERROR("Failed to write file: %s, %s", path.c_str(),
181+
ailego::FileHelper::GetLastErrorString().c_str());
185182
return IndexError_WriteData;
186183
}
187184
return this->init_index_mapping(len);
@@ -310,8 +307,8 @@ int IndexMapping::append(const std::string &id, size_t size) {
310307
}
311308

312309
if (!copy_on_write_ && !file_.truncate(index_size_ + size)) {
313-
LOG_ERROR("Failed to truncate file, errno %d, %s", errno,
314-
std::strerror(errno));
310+
LOG_ERROR("Failed to truncate file, %s",
311+
ailego::FileHelper::GetLastErrorString().c_str());
315312
return IndexError_TruncateFile;
316313
}
317314

@@ -425,8 +422,8 @@ void IndexMapping::unmap_all(void) {
425422

426423
int IndexMapping::flush(void) {
427424
if ((file_.size() < index_size_) && !file_.truncate(index_size_)) {
428-
LOG_ERROR("Failed to truncate file size %zu, errno %d, %s", index_size_,
429-
errno, std::strerror(errno));
425+
LOG_ERROR("Failed to truncate file size %zu, %s", index_size_,
426+
ailego::FileHelper::GetLastErrorString().c_str());
430427
return IndexError_TruncateFile;
431428
}
432429

@@ -443,8 +440,8 @@ int IndexMapping::flush(void) {
443440
segment_info.segment_header->content_offset +
444441
item->meta()->data_index;
445442
if (file_.write(off, item->data(), segment_size) != segment_size) {
446-
LOG_ERROR("Failed to write segment, size %zu, errno %d, %s",
447-
segment_size, errno, std::strerror(errno));
443+
LOG_ERROR("Failed to write segment, size %zu, %s", segment_size,
444+
ailego::FileHelper::GetLastErrorString().c_str());
448445
return IndexError_WriteData;
449446
}
450447
} else {
@@ -464,8 +461,9 @@ int IndexMapping::flush(void) {
464461
auto header = item.second;
465462
if (file_.write(header_start_offset, header, header->content_offset) !=
466463
header->content_offset) {
467-
LOG_ERROR("Failed to write segment, size %lu, errno %d, %s",
468-
header->content_offset, errno, std::strerror(errno));
464+
LOG_ERROR("Failed to write segment, size %lu, %s",
465+
header->content_offset,
466+
ailego::FileHelper::GetLastErrorString().c_str());
469467
return IndexError_WriteData;
470468
}
471469
}
@@ -487,7 +485,8 @@ int IndexMapping::init_index_mapping(size_t len) {
487485
uint8_t *start = reinterpret_cast<uint8_t *>(ailego::File::MemoryMap(
488486
file_.native_handle(), current_header_start_offset_, len, opts));
489487
if (!start) {
490-
LOG_ERROR("Failed to map file, errno %d, %s", errno, std::strerror(errno));
488+
LOG_ERROR("Failed to map file, %s",
489+
ailego::FileHelper::GetLastErrorString().c_str());
491490
return IndexError_MMapFile;
492491
}
493492

src/core/utility/file_dumper.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
14-
#include <cerrno>
1514
#include <zvec/ailego/io/file.h>
15+
#include <zvec/ailego/utility/file_helper.h>
1616
#include <zvec/core/framework/index_error.h>
1717
#include <zvec/core/framework/index_factory.h>
1818
#include <zvec/core/framework/index_format.h>
@@ -54,17 +54,17 @@ struct FileDumper : public IndexDumper {
5454
}
5555

5656
if (!file_.create(path.c_str(), sizeof(IndexFormat::MetaHeader))) {
57-
LOG_ERROR("Failed to create file %s, errno %d, %s", path.c_str(), errno,
58-
std::strerror(errno));
57+
LOG_ERROR("Failed to create file %s, %s", path.c_str(),
58+
ailego::FileHelper::GetLastErrorString().c_str());
5959
return IndexError_CreateFile;
6060
}
6161

6262
auto write_data = [this](const void *buf, size_t size) {
6363
return this->file_.write(buf, size);
6464
};
6565
if (!packer_.setup(write_data)) {
66-
LOG_ERROR("Failed to setup index package, errno %d, %s", errno,
67-
std::strerror(errno));
66+
LOG_ERROR("Failed to setup index package, %s",
67+
ailego::FileHelper::GetLastErrorString().c_str());
6868
return IndexError_WriteData;
6969
}
7070
return 0;

src/core/utility/file_read_storage.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
14-
#include <cerrno>
1514
#include <ailego/utility/memory_helper.h>
1615
#include <zvec/ailego/io/file.h>
16+
#include <zvec/ailego/utility/file_helper.h>
1717
#include <zvec/core/framework/index_error.h>
1818
#include <zvec/core/framework/index_factory.h>
1919
#include <zvec/core/framework/index_unpacker.h>
@@ -391,13 +391,13 @@ class FileReadStorage : public IndexStorage {
391391
bool direct_io) {
392392
auto file_ptr = std::make_shared<ailego::File>();
393393
if (!file_ptr) {
394-
LOG_ERROR("Failed to create file object, errno %d, %s", errno,
395-
std::strerror(errno));
394+
LOG_ERROR("Failed to create file object, %s",
395+
ailego::FileHelper::GetLastErrorString().c_str());
396396
return nullptr;
397397
}
398398
if (!file_ptr->open(path, true, direct_io)) {
399-
LOG_ERROR("Failed to open file %s, errno %d, %s", path.c_str(), errno,
400-
std::strerror(errno));
399+
LOG_ERROR("Failed to open file %s, %s", path.c_str(),
400+
ailego::FileHelper::GetLastErrorString().c_str());
401401
return nullptr;
402402
}
403403
return file_ptr;

src/core/utility/memory_dumper.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
14-
#include <cerrno>
14+
#include <zvec/ailego/utility/file_helper.h>
1515
#include <zvec/core/framework/index_error.h>
1616
#include <zvec/core/framework/index_factory.h>
1717
#include <zvec/core/framework/index_format.h>
@@ -48,8 +48,8 @@ struct MemoryDumper : public IndexDumper {
4848
int create(const std::string &path) override {
4949
rope_ = IndexMemory::Instance()->create(path);
5050
if (!rope_) {
51-
LOG_ERROR("Failed to create memory block %s, errno %d, %s", path.c_str(),
52-
errno, std::strerror(errno));
51+
LOG_ERROR("Failed to create memory block %s, %s", path.c_str(),
52+
ailego::FileHelper::GetLastErrorString().c_str());
5353
return IndexError_CreateFile;
5454
}
5555
// Append a memory block
@@ -59,8 +59,8 @@ struct MemoryDumper : public IndexDumper {
5959
return (*this->rope_)[0].append(buf, size);
6060
};
6161
if (!packer_.setup(write_data)) {
62-
LOG_ERROR("Failed to setup index package, errno %d, %s", errno,
63-
std::strerror(errno));
62+
LOG_ERROR("Failed to setup index package, %s",
63+
ailego::FileHelper::GetLastErrorString().c_str());
6464
return IndexError_WriteData;
6565
}
6666
return 0;

src/core/utility/mmap_file_read_storage.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
14-
#include <cerrno>
1514
#include <zvec/ailego/io/mmap_file.h>
15+
#include <zvec/ailego/utility/file_helper.h>
1616
#include <zvec/core/framework/index_factory.h>
1717
#include <zvec/core/framework/index_format.h>
1818
#include <zvec/core/framework/index_unpacker.h>
@@ -176,14 +176,14 @@ class MMapFileReadStorage : public IndexStorage {
176176
int open(const std::string &path, bool) override {
177177
file_ptr_ = std::make_shared<ailego::MMapFile>();
178178
if (!file_ptr_) {
179-
LOG_ERROR("Failed to create mmap file object, errno %d, %s", errno,
180-
std::strerror(errno));
179+
LOG_ERROR("Failed to create mmap file object, %s",
180+
ailego::FileHelper::GetLastErrorString().c_str());
181181
return IndexError_NoMemory;
182182
}
183183

184184
if (!file_ptr_->open(path.c_str(), true, memory_shared_)) {
185-
LOG_ERROR("Failed to open file %s, errno %d, %s", path.c_str(), errno,
186-
std::strerror(errno));
185+
LOG_ERROR("Failed to open file %s, %s", path.c_str(),
186+
ailego::FileHelper::GetLastErrorString().c_str());
187187
return IndexError_OpenFile;
188188
}
189189

@@ -193,8 +193,8 @@ class MMapFileReadStorage : public IndexStorage {
193193
(footer_offset_ > 0 ? 0 : file_ptr_->size()) + footer_offset_;
194194
size_t size = end_offset > index_offset_ ? end_offset - index_offset_ : 0;
195195
if (memory_locked_ && !file_ptr_->lock()) {
196-
LOG_WARN("Failed to lock pages with size %zu, errno %d, %s",
197-
file_ptr_->size(), errno, std::strerror(errno));
196+
LOG_WARN("Failed to lock pages with size %zu, %s", file_ptr_->size(),
197+
ailego::FileHelper::GetLastErrorString().c_str());
198198
}
199199
if (memory_warmup_ && !checksum_validation_) {
200200
ailego::File::MemoryWarmup(

src/db/collection.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,8 +1739,9 @@ Status CollectionImpl::create() {
17391739
CHECK_RETURN_STATUS(s);
17401740

17411741
if (!ailego::FileHelper::MakePath(path_.c_str())) {
1742-
return Status::InvalidArgument("create collection path failed: ", path_,
1743-
", error: ", strerror(errno));
1742+
return Status::InvalidArgument(
1743+
"create collection path failed: ", path_,
1744+
", error: ", ailego::FileHelper::GetLastErrorString());
17441745
}
17451746

17461747
// init lock file

src/db/common/typedef.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ using idx_t = uint64_t;
4040
#define CLOG_FATAL(format, ...) \
4141
LOG_FATAL(format COLLECTION_FORMAT, ##__VA_ARGS__, collection_name().c_str())
4242

43-
#define ELOG_ERROR(format, ...) \
44-
LOG_ERROR(format " errno[%s] ", ##__VA_ARGS__, std::strerror(errno))
45-
4643
#define WAL_FORMAT " wal_path_[%s] "
4744

4845
#define WLOG_DEBUG(format, ...) \

src/db/index/common/version_manager.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Status Version::Save(const std::string &path, const Version &version) {
7777
std::ofstream ofs(path, std::ios::binary);
7878
if (!ofs.is_open()) {
7979
LOG_ERROR("Failed to open file: %s, err: %s", path.c_str(),
80-
strerror(errno));
80+
ailego::FileHelper::GetLastErrorString().c_str());
8181
return Status::InternalError("Failed to open file: %s", path.c_str());
8282
}
8383

src/include/zvec/ailego/utility/file_helper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ struct FileHelper {
7777
//! Retrieve non-zero if two paths are pointing to the same file
7878
static bool IsSame(const char *path1, const char *path2);
7979

80+
//! Retrieve a human-readable string for the most recent OS error
81+
//! (GetLastError() on Windows, strerror(errno) on POSIX)
82+
static std::string GetLastErrorString();
83+
8084
//! Retrieve the size of a file
8185
static size_t FileSize(const char *path) {
8286
size_t file_size = 0;

0 commit comments

Comments
 (0)