Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Now catch std::filesystem exceptions in parameters #1127

Merged
merged 2 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ set(SIMPLNX_HDRS
${SIMPLNX_SOURCE_DIR}/Common/DataTypeUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Common/DataVector.hpp
${SIMPLNX_SOURCE_DIR}/Common/EulerAngle.hpp
${SIMPLNX_SOURCE_DIR}/Common/Filesystem.hpp
${SIMPLNX_SOURCE_DIR}/Common/IteratorUtility.hpp
${SIMPLNX_SOURCE_DIR}/Common/Numbers.hpp
${SIMPLNX_SOURCE_DIR}/Common/Range.hpp
Expand Down
21 changes: 21 additions & 0 deletions src/simplnx/Common/Filesystem.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include "simplnx/Common/Result.hpp"

#include <nonstd/expected.hpp>

#include <filesystem>

namespace nx::core::filesystem
{
inline Result<bool> exists(const std::filesystem::path& path)
{
std::error_code errorCode;
bool result = std::filesystem::exists(path, errorCode);
if(errorCode)
{
return MakeErrorResult<bool>(errorCode.value(), errorCode.message());
}
return {result};
}
} // namespace nx::core::filesystem
28 changes: 17 additions & 11 deletions src/simplnx/Parameters/Dream3dImportParameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,27 @@ Result<> Dream3dImportParameter::validate(const std::any& value) const
//-----------------------------------------------------------------------------
Result<> Dream3dImportParameter::validatePath(const ValueType& importData) const
{
std::filesystem::path path = importData.FilePath;
if(!fs::exists(path))
try
{
return MakeErrorResult(-2, fmt::format("Path '{}' does not exist", path.string()));
}
std::filesystem::path path = importData.FilePath;
if(!fs::exists(path))
{
return MakeErrorResult(-2, fmt::format("Path '{}' does not exist", path.string()));
}

if(!fs::is_regular_file(path))
{
return MakeErrorResult(-3, fmt::format("Path '{}' is not a file", path.string()));
}
if(!fs::is_regular_file(path))
{
return MakeErrorResult(-3, fmt::format("Path '{}' is not a file", path.string()));
}

nx::core::HDF5::FileReader fileReader(path);
if(!fileReader.isValid())
nx::core::HDF5::FileReader fileReader(path);
if(!fileReader.isValid())
{
return MakeErrorResult(-4, fmt::format("HDF5 file at path '{}' could not be read", path.string()));
}
} catch(const fs::filesystem_error& exception)
{
return MakeErrorResult(-4, fmt::format("HDF5 file at path '{}' could not be read", path.string()));
return MakeErrorResult(-5, fmt::format("Filesystem excpetion: {}", exception.what()));
}
return {};
}
Expand Down
130 changes: 81 additions & 49 deletions src/simplnx/Parameters/FileSystemPathParameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,67 +25,93 @@ namespace
//-----------------------------------------------------------------------------
Result<> ValidateInputFile(const FileSystemPathParameter::ValueType& path)
{
if(!fs::exists(path))
try
{
return MakeErrorResult(-2, fmt::format("File System Path '{}' does not exist", path.string()));
}
if(!fs::exists(path))
{
return MakeErrorResult(-2, fmt::format("File System Path '{}' does not exist", path.string()));
}

if(!fs::is_regular_file(path))
if(!fs::is_regular_file(path))
{
return MakeErrorResult(-3, fmt::format("File System Path '{}' is not a file", path.string()));
}
} catch(const fs::filesystem_error& exception)
{
return MakeErrorResult(-3, fmt::format("File System Path '{}' is not a file", path.string()));
return MakeErrorResult(-9, fmt::format("Filesystem excpetion: {}", exception.what()));
}
return {};
}

//-----------------------------------------------------------------------------
Result<> ValidateInputDir(const FileSystemPathParameter::ValueType& path)
{
if(!fs::exists(path))

try
{
return MakeErrorResult(-4, fmt::format("File System Path '{}' does not exist", path.string()));
}
if(!fs::is_directory(path))
if(!fs::exists(path))
{
return MakeErrorResult(-4, fmt::format("File System Path '{}' does not exist", path.string()));
}
if(!fs::is_directory(path))
{
return MakeErrorResult(-5, fmt::format("File System Path '{}' is not a file", path.string()));
}
} catch(const fs::filesystem_error& exception)
{
return MakeErrorResult(-5, fmt::format("File System Path '{}' is not a file", path.string()));
return MakeErrorResult(-10, fmt::format("Filesystem excpetion: {}", exception.what()));
}

return {};
}

//-----------------------------------------------------------------------------
Result<> ValidateOutputFile(const FileSystemPathParameter::ValueType& path)
{
if(fs::exists(path) && fs::is_directory(path))
try
{
return MakeErrorResult(-8, fmt::format("File System Path '{}' exists AND is a directory. The Parameter is set to save a file.", path.string()));
}
if(fs::exists(path) && fs::is_directory(path))
{
return MakeErrorResult(-8, fmt::format("File System Path '{}' exists AND is a directory. The Parameter is set to save a file.", path.string()));
}

auto result = FileUtilities::ValidateDirectoryWritePermission(path, true);
if(result.invalid())
{
return result;
}
if(!fs::exists(path))
auto result = FileUtilities::ValidateDirectoryWritePermission(path, true);
if(result.invalid())
{
return result;
}
if(!fs::exists(path))
{
return MakeWarningVoidResult(-6, fmt::format("File System Path '{}' does not exist. It will be created during execution.", path.string()));
}
} catch(const fs::filesystem_error& exception)
{
return MakeWarningVoidResult(-6, fmt::format("File System Path '{}' does not exist. It will be created during execution.", path.string()));
return MakeErrorResult(-11, fmt::format("Filesystem excpetion: {}", exception.what()));
}

return {};
}

//-----------------------------------------------------------------------------
Result<> ValidateOutputDir(const FileSystemPathParameter::ValueType& path)
{
auto result = FileUtilities::ValidateDirectoryWritePermission(path, false);
if(result.invalid())
try
{
return result;
}
if(!fs::exists(path))
auto result = FileUtilities::ValidateDirectoryWritePermission(path, false);
if(result.invalid())
{
return result;
}
if(!fs::exists(path))
{
return MakeWarningVoidResult(-7, fmt::format("File System Path '{}' does not exist. It will be created during execution.", path.string()));
}
} catch(const fs::filesystem_error& exception)
{
return MakeWarningVoidResult(-7, fmt::format("File System Path '{}' does not exist. It will be created during execution.", path.string()));
return MakeErrorResult(-12, fmt::format("Filesystem excpetion: {}", exception.what()));
}
return {};
}

} // namespace

namespace nx::core
Expand Down Expand Up @@ -204,36 +230,42 @@ Result<> FileSystemPathParameter::validate(const std::any& value) const
//-----------------------------------------------------------------------------
Result<> FileSystemPathParameter::validatePath(const ValueType& path) const
{
const std::string prefix = fmt::format("Parameter Name: '{}'\n Parameter Key: '{}'\n Validation Error: ", humanName(), name());

if(path.empty())
try
{
return nx::core::MakeErrorResult(-3001, fmt::format("{} File System Path must not be empty", prefix));
}
const std::string prefix = fmt::format("Parameter Name: '{}'\n Parameter Key: '{}'\n Validation Error: ", humanName(), name());

if(!m_acceptAllExtensions && (m_PathType == nx::core::FileSystemPathParameter::PathType::InputFile || m_PathType == nx::core::FileSystemPathParameter::PathType::OutputFile))
{
if(!path.has_extension())
if(path.empty())
{
return {nonstd::make_unexpected(std::vector<Error>{{-3002, fmt::format("{} File System Path must include a file extension.\n FilePath: '{}'", prefix, path.string())}})};
return nx::core::MakeErrorResult(-3001, fmt::format("{} File System Path must not be empty", prefix));
}
std::string lowerExtension = nx::core::StringUtilities::toLower(path.extension().string());
if(path.has_extension() && !m_AvailableExtensions.empty() && m_AvailableExtensions.find(lowerExtension) == m_AvailableExtensions.end())

if(!m_acceptAllExtensions && (m_PathType == nx::core::FileSystemPathParameter::PathType::InputFile || m_PathType == nx::core::FileSystemPathParameter::PathType::OutputFile))
{
return {nonstd::make_unexpected(std::vector<Error>{{-3003, fmt::format("{} File extension '{}' is not a valid file extension", prefix, path.extension().string())}})};
if(!path.has_extension())
{
return {nonstd::make_unexpected(std::vector<Error>{{-3002, fmt::format("{} File System Path must include a file extension.\n FilePath: '{}'", prefix, path.string())}})};
}
std::string lowerExtension = nx::core::StringUtilities::toLower(path.extension().string());
if(path.has_extension() && !m_AvailableExtensions.empty() && m_AvailableExtensions.find(lowerExtension) == m_AvailableExtensions.end())
{
return {nonstd::make_unexpected(std::vector<Error>{{-3003, fmt::format("{} File extension '{}' is not a valid file extension", prefix, path.extension().string())}})};
}
}
}

switch(m_PathType)
switch(m_PathType)
{
case nx::core::FileSystemPathParameter::PathType::InputFile:
return ValidateInputFile(path);
case nx::core::FileSystemPathParameter::PathType::InputDir:
return ValidateInputDir(path);
case nx::core::FileSystemPathParameter::PathType::OutputFile:
return ValidateOutputFile(path);
case nx::core::FileSystemPathParameter::PathType::OutputDir:
return ValidateOutputDir(path);
}
} catch(const fs::filesystem_error& exception)
{
case nx::core::FileSystemPathParameter::PathType::InputFile:
return ValidateInputFile(path);
case nx::core::FileSystemPathParameter::PathType::InputDir:
return ValidateInputDir(path);
case nx::core::FileSystemPathParameter::PathType::OutputFile:
return ValidateOutputFile(path);
case nx::core::FileSystemPathParameter::PathType::OutputDir:
return ValidateOutputDir(path);
return MakeErrorResult(-9, fmt::format("Filesystem excpetion: {}", exception.what()));
}

return {};
Expand Down
49 changes: 27 additions & 22 deletions src/simplnx/Parameters/GeneratedFileListParameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,36 +150,41 @@ std::any GeneratedFileListParameter::defaultValue() const
//-----------------------------------------------------------------------------
Result<> GeneratedFileListParameter::validate(const std::any& valueRef) const
{
const std::string prefix = fmt::format("Parameter Name: '{}'\n Parameter Key: '{}'\n Validation Error: ", humanName(), name());
try
{
const std::string prefix = fmt::format("Parameter Name: '{}'\n Parameter Key: '{}'\n Validation Error: ", humanName(), name());

const auto& value = GetAnyRef<ValueType>(valueRef);
const auto& value = GetAnyRef<ValueType>(valueRef);

if(value.inputPath.empty())
{
return nx::core::MakeErrorResult(nx::core::FilterParameter::Constants::k_Validate_Empty_Value, fmt::format("{}Input Path cannot be empty.", prefix));
}
if(value.inputPath.empty())
{
return nx::core::MakeErrorResult(nx::core::FilterParameter::Constants::k_Validate_Empty_Value, fmt::format("{}Input Path cannot be empty.", prefix));
}

if(value.startIndex > value.endIndex)
{
return nx::core::MakeErrorResult(-4002, fmt::format("{}startIndex must be less than or equal to endIndex.", prefix));
}
// Generate the file list
auto fileList = value.generate();
// Validate that they all exist
std::vector<Error> errors;
for(const auto& currentFilePath : fileList)
{
if(!fs::exists(currentFilePath))
if(value.startIndex > value.endIndex)
{
errors.push_back({-4003, fmt::format("{}FILE DOES NOT EXIST: '{}'", prefix, currentFilePath)});
return nx::core::MakeErrorResult(-4002, fmt::format("{}startIndex must be less than or equal to endIndex.", prefix));
}
// Generate the file list
auto fileList = value.generate();
// Validate that they all exist
std::vector<Error> errors;
for(const auto& currentFilePath : fileList)
{
if(!fs::exists(currentFilePath))
{
errors.push_back({-4003, fmt::format("{}FILE DOES NOT EXIST: '{}'", prefix, currentFilePath)});
}
}
}

if(!errors.empty())
if(!errors.empty())
{
return {nonstd::make_unexpected(std::move(errors))};
}
} catch(const fs::filesystem_error& exception)
{
return {nonstd::make_unexpected(std::move(errors))};
return MakeErrorResult(-4004, fmt::format("Filesystem excpetion: {}", exception.what()));
}

return {};
}

Expand Down
Loading