Skip to content

Commit

Permalink
Improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
visuve committed Apr 13, 2024
1 parent f673de4 commit 516c964
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 80 deletions.
62 changes: 1 addition & 61 deletions PystykorvaCLI/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,66 +32,6 @@ Pystykorva::Options Deserialize(const CmdArgs& args)
return options;
}

std::string StatusMaskToString(uint32_t statusMask)
{
if (!statusMask)
{
return "ok";
}

std::string result;
std::string delimiter;

for (uint32_t bit = 1; statusMask; statusMask &= ~bit, bit <<= 1)
{
switch (statusMask & bit)
{
case Pystykorva::Status::Missing:
result += delimiter + "the file is missing";
delimiter = ", ";
break;
case Pystykorva::Status::NoPermission:
result += delimiter + "incorrect permissions";
delimiter = ", ";
break;
case Pystykorva::Status::NameExcluded:
result += delimiter + "excluded by name";
delimiter = ", ";
break;
case Pystykorva::Status::TooSmall:
result += delimiter + "too small file size";
delimiter = ", ";
break;
case Pystykorva::Status::TooBig:
result += delimiter + "too large file size";
delimiter = ", ";
break;
case Pystykorva::Status::TooEarly:
result += delimiter + "file cretead too early";
delimiter = ", ";
break;
case Pystykorva::Status::TooLate:
result += delimiter + "file cretead too late";
delimiter = ", ";
break;
case Pystykorva::Status::EncodingError:
result += delimiter + "probably a binary file";
delimiter = ", ";
break;
case Pystykorva::Status::ConversionError:
result += delimiter + "unicode conversion error";
delimiter = ", ";
break;
case Pystykorva::Status::IOError:
result += delimiter + "i/o error";
delimiter = ", ";
break;
}
}

return result;
}

Console& operator << (Console& stream, const Pystykorva::Match& result)
{
constexpr static std::u16string_view RedColorTagBegin = u"\033[31m";
Expand Down Expand Up @@ -157,7 +97,7 @@ void ReportResults(
}

#if _DEBUG
Cout << path << " processed, status: " << StatusMaskToString(result.StatusMask)
Cout << path << " processed, status: " << Pystykorva::StatusMaskToString(result.StatusMask)
<< ", encoding: " << result.Encoding.Name << ", confidence: " << result.Encoding.Confidence
<< ", matches: " << result.Matches.size() << '\n';
#endif
Expand Down
22 changes: 16 additions & 6 deletions PystykorvaLib/MemoryMappedFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
#define NOMINMAX
#include <Windows.h>

IOException::IOException(const std::string& message) :
std::system_error(GetLastError(), std::system_category(), message)
{
}

class MemoryMappedFileImpl
{
public:
Expand All @@ -21,7 +26,7 @@ class MemoryMappedFileImpl
{
if (!_file || _file == INVALID_HANDLE_VALUE)
{
throw std::system_error(GetLastError(), std::system_category(), "CreateFileW");
throw IOException("CreateFileW");
}

LARGE_INTEGER mappingSize;
Expand All @@ -37,14 +42,14 @@ class MemoryMappedFileImpl

if (!_mapping)
{
throw std::system_error(GetLastError(), std::system_category(), "CreateFileMappingW");
throw IOException("CreateFileMappingW");
}

_view = MapViewOfFile(_mapping, FILE_MAP_ALL_ACCESS, 0, 0, fileSize);

if (!_view)
{
throw std::system_error(GetLastError(), std::system_category(), "MapViewOfFile");
throw IOException("MapViewOfFile");
}

_size = fileSize;
Expand Down Expand Up @@ -88,6 +93,11 @@ class MemoryMappedFileImpl
};
#else

IOException::IOException(const std::string& message) :
std::system_error(errno, std::system_category(), message)
{
}

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
Expand All @@ -101,14 +111,14 @@ class MemoryMappedFileImpl
{
if (_descriptor == -1)
{
throw std::system_error(errno, std::system_category(), "open");
throw IOException("open");
}

_view = mmap(nullptr, _size, PROT_READ, MAP_PRIVATE, _descriptor, 0);

if (_view == MAP_FAILED)
{
throw std::system_error(errno, std::system_category(), "mmap");
throw IOException("mmap");
}

_size = fileSize;
Expand Down Expand Up @@ -159,4 +169,4 @@ std::string_view MemoryMappedFile::Sample(size_t size) const
std::string_view MemoryMappedFile::Data() const
{
return _impl->Data();
}
}
5 changes: 4 additions & 1 deletion PystykorvaLib/MemoryMappedFile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

class MemoryMappedFileImpl;

// This interface has no other meaning than to allow testing
struct IOException : std::system_error
{
IOException(const std::string& message);
};

class MemoryMappedFile : public Pystykorva::IFile
{
Expand Down
72 changes: 72 additions & 0 deletions PystykorvaLib/Pystykorva.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,78 @@ void Pystykorva::Stop()
_threads.clear();
}

std::string Pystykorva::StatusMaskToString(uint32_t statusMask)
{
if (!statusMask)
{
return "ok";
}

std::string result;
std::string delimiter;

for (uint32_t bit = 1; statusMask; statusMask &= ~bit, bit <<= 1)
{
switch (statusMask & bit)
{
case Pystykorva::Status::Missing:
result += delimiter + "the file is missing";
delimiter = ", ";
break;
case Pystykorva::Status::NoPermission:
result += delimiter + "incorrect permissions";
delimiter = ", ";
break;
case Pystykorva::Status::NameExcluded:
result += delimiter + "excluded by name";
delimiter = ", ";
break;
case Pystykorva::Status::TooSmall:
result += delimiter + "too small file size";
delimiter = ", ";
break;
case Pystykorva::Status::TooBig:
result += delimiter + "too large file size";
delimiter = ", ";
break;
case Pystykorva::Status::TooEarly:
result += delimiter + "file cretead too early";
delimiter = ", ";
break;
case Pystykorva::Status::TooLate:
result += delimiter + "file cretead too late";
delimiter = ", ";
break;
case Pystykorva::Status::IOError:
result += delimiter + "i/o error";
delimiter = ", ";
break;
case Pystykorva::Status::EncodingError:
result += delimiter + "encoding error";
delimiter = ", ";
break;
case Pystykorva::Status::ConversionError:
result += delimiter + "unicode conversion error";
delimiter = ", ";
break;
case Pystykorva::Status::AnalysisError:
result += delimiter + "line analysis error";
delimiter = ", ";
break;
case Pystykorva::Status::SearchError:
result += delimiter + "line search error";
delimiter = ", ";
break;
case Pystykorva::Status::UnknownError:
result += delimiter + "unknown error";
delimiter = ", ";
break;
}
}

return result;
}

bool Pystykorva::IsExcludedDirectory(const std::filesystem::path& path) const
{
return std::any_of(
Expand Down
21 changes: 12 additions & 9 deletions PystykorvaLib/Pystykorva.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ class Pystykorva

MatchMode Mode = PlainCaseSensitive;

uint64_t MinimumSize = 0;
uint64_t MinimumSize = 1;
uint64_t MaximumSize = std::numeric_limits<uint64_t>::max();

std::chrono::time_point<std::chrono::file_clock> MinimumTime;
std::chrono::time_point<std::chrono::file_clock> MinimumTime = std::chrono::file_clock::now() - std::chrono::years(1000);
std::chrono::time_point<std::chrono::file_clock> MaximumTime = std::chrono::file_clock::now() + std::chrono::years(1000);

uint32_t MaximumThreads = std::thread::hardware_concurrency();
Expand All @@ -41,17 +41,18 @@ class Pystykorva
{
Ok = 0x00,
Missing = (1u << 0),
NameExcluded = (1u << 1),
NoPermission = (1u << 2),
NoPermission = (1u << 1),
NameExcluded = (1u << 2),
TooSmall = (1u << 3),
TooBig = (1u << 4),
TooEarly = (1u << 5),
TooLate = (1u << 6),
EncodingError = (1u << 7),
ConversionError = (1u << 8),
AnalysisError = (1u << 9),
SearchError = (1u << 10),
IOError = (1u << 11)
IOError = (1u << 7),
EncodingError = (1u << 8),
ConversionError = (1u << 9),
AnalysisError = (1u << 10),
SearchError = (1u << 11),
UnknownError = (1u << 12)
};

struct Position
Expand Down Expand Up @@ -141,6 +142,8 @@ class Pystykorva
void Wait();
void Stop();

static std::string StatusMaskToString(uint32_t);

private:
bool IsExcludedDirectory(const std::filesystem::path&) const;
std::filesystem::path Next();
Expand Down
8 changes: 6 additions & 2 deletions PystykorvaLib/TextProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Pystykorva::Result TextProcessor::ProcessFile(const std::filesystem::path& path)

uint64_t fileSize = std::filesystem::file_size(path);

if (fileSize < _options.MinimumSize || fileSize == 0)
if (fileSize == 0 || fileSize < _options.MinimumSize)
{
result.StatusMask |= Pystykorva::Status::TooSmall;
}
Expand Down Expand Up @@ -67,6 +67,10 @@ Pystykorva::Result TextProcessor::ProcessFile(const std::filesystem::path& path)

FindAll(file, result.Matches, result.Encoding);
}
catch (const IOException&)
{
result.StatusMask |= Pystykorva::Status::IOError;
}
catch (const EncodingException&)
{
result.StatusMask |= Pystykorva::Status::EncodingError;
Expand All @@ -85,7 +89,7 @@ Pystykorva::Result TextProcessor::ProcessFile(const std::filesystem::path& path)
}
catch (const std::exception&)
{
result.StatusMask |= Pystykorva::Status::IOError;
result.StatusMask |= Pystykorva::Status::UnknownError;
}

return result;
Expand Down
2 changes: 1 addition & 1 deletion PystykorvaTests/PystykorvaTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ TEST(PystykorvaTests, SearchSuccess)

for (auto& [_, result] : results)
{
EXPECT_EQ(result.StatusMask, Pystykorva::Ok);
EXPECT_STREQ(Pystykorva::StatusMaskToString(result.StatusMask).c_str(), "ok");
EXPECT_EQ(result.Matches.size(), 15);
}

Expand Down

0 comments on commit 516c964

Please sign in to comment.