aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-01-29 13:38:17 +0100
committerGitHub <[email protected]>2024-01-29 13:38:17 +0100
commitb6f3294987f4e1bc9ec1f2fe83a4f5570cb89284 (patch)
treea240bcba5fb0fee915447db71c3801003b9b07d7
parent0.2.39 (diff)
downloadzen-b6f3294987f4e1bc9ec1f2fe83a4f5570cb89284.tar.xz
zen-b6f3294987f4e1bc9ec1f2fe83a4f5570cb89284.zip
exception on basicfile read error (#642)
* Change BasicFile::Read to throw exception like IoBuffer - Don't ASSERT on dwNumberOfBytesRead == NumberOfBytesToRead - throw exception with details instead - Use proper return type for pread()
-rw-r--r--CHANGELOG.md3
-rw-r--r--src/zencore/iobuffer.cpp4
-rw-r--r--src/zenutil/basicfile.cpp36
3 files changed, 33 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3b336ffd1..bc1d7a2a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,7 @@
##
+- Improvement: Add details when reading from BasicFile fails (number of bytes read is not expected size)
+
+## 0.2.39
- Feature: add `--ignore-missing-attachments` to `oplog-import` command
- Feature: add `--ignore-missing-attachments` to `oplog-export` command
- Improvement: Removed use of <random> in stats, for better performance (runtime as well as build)
diff --git a/src/zencore/iobuffer.cpp b/src/zencore/iobuffer.cpp
index 80d0f4ee4..54f2aaee8 100644
--- a/src/zencore/iobuffer.cpp
+++ b/src/zencore/iobuffer.cpp
@@ -327,8 +327,8 @@ IoBufferExtendedCore::Materialize() const
}
#else
static_assert(sizeof(off_t) >= sizeof(uint64_t), "sizeof(off_t) does not support large files");
- int Fd = int(uintptr_t(m_FileHandle));
- int ReadResult = pread(Fd, (void*)m_DataPtr, m_DataBytes, m_FileOffset);
+ int Fd = int(uintptr_t(m_FileHandle));
+ ssize_t ReadResult = pread(Fd, (void*)m_DataPtr, m_DataBytes, m_FileOffset);
if (ReadResult != -1)
{
BytesRead = size_t(ReadResult);
diff --git a/src/zenutil/basicfile.cpp b/src/zenutil/basicfile.cpp
index dbae76717..ad98bf652 100644
--- a/src/zenutil/basicfile.cpp
+++ b/src/zenutil/basicfile.cpp
@@ -171,6 +171,8 @@ BasicFile::Read(void* Data, uint64_t BytesToRead, uint64_t FileOffset)
while (BytesToRead)
{
const uint64_t NumberOfBytesToRead = Min(BytesToRead, MaxChunkSize);
+ int32_t Error = 0;
+ size_t BytesRead = 0;
#if ZEN_PLATFORM_WINDOWS
OVERLAPPED Ovl{};
@@ -180,19 +182,37 @@ BasicFile::Read(void* Data, uint64_t BytesToRead, uint64_t FileOffset)
DWORD dwNumberOfBytesRead = 0;
BOOL Success = ::ReadFile(m_FileHandle, Data, DWORD(NumberOfBytesToRead), &dwNumberOfBytesRead, &Ovl);
-
- ZEN_ASSERT(dwNumberOfBytesRead == NumberOfBytesToRead);
+ if (Success)
+ {
+ BytesRead = size_t(dwNumberOfBytesRead);
+ }
+ else
+ {
+ Error = zen::GetLastError();
+ }
#else
static_assert(sizeof(off_t) >= sizeof(uint64_t), "sizeof(off_t) does not support large files");
- int Fd = int(uintptr_t(m_FileHandle));
- int BytesRead = pread(Fd, Data, NumberOfBytesToRead, FileOffset);
- bool Success = (BytesRead > 0);
+ int Fd = int(uintptr_t(m_FileHandle));
+ ssize_t ReadResult = pread(Fd, Data, NumberOfBytesToRead, FileOffset);
+ if (ReadResult != -1)
+ {
+ BytesRead = size_t(ReadResult);
+ }
+ else
+ {
+ Error = zen::GetLastError();
+ }
#endif
- if (!Success)
+ if (Error || (BytesRead != NumberOfBytesToRead))
{
- std::error_code Dummy;
- ThrowLastError(fmt::format("Failed to read from file '{}'", zen::PathFromHandle(m_FileHandle, Dummy)));
+ std::error_code DummyEc;
+ throw std::system_error(std::error_code(Error, std::system_category()),
+ fmt::format("ReadFile/pread failed (offset {:#x}, size {:#x}) file: '{}' (size {:#x})",
+ FileOffset,
+ NumberOfBytesToRead,
+ PathFromHandle(m_FileHandle, DummyEc),
+ FileSizeFromHandle(m_FileHandle)));
}
BytesToRead -= NumberOfBytesToRead;