diff --git a/src/libs/core/helper/parse_json.hpp b/src/libs/core/helper/parse_json.hpp index 1f3fffa3..23b9117f 100644 --- a/src/libs/core/helper/parse_json.hpp +++ b/src/libs/core/helper/parse_json.hpp @@ -5,9 +5,10 @@ // better json error messages, see https://json.nlohmann.me/api/macros/json_diagnostics/ #define JSON_DIAGNOSTICS 1 // NOLINT(cppcoreguidelines-macro-usage) #endif - #include +#include + #include "./expected.hpp" #include "./windows.hpp" @@ -49,6 +50,12 @@ NLOHMANN_JSON_NAMESPACE_END namespace json { + enum class ParseError : u8 { + OpenError, + ReadError, + FormatError, + }; + template [[nodiscard]] helper::expected try_parse_json(const std::string& content) noexcept { @@ -68,22 +75,43 @@ namespace json { } template - [[nodiscard]] helper::expected try_parse_json_file(const std::filesystem::path& file) noexcept { + [[nodiscard]] helper::expected> try_parse_json_file( + const std::filesystem::path& file + ) noexcept { if (not std::filesystem::exists(file)) { - return helper::unexpected{ fmt::format("File '{}' doesn't exist", file.string()) }; + return helper::unexpected>{ std::make_pair( + fmt::format("File '{}' doesn't exist", file.string()), ParseError::OpenError + ) }; } std::ifstream file_stream{ file }; if (not file_stream.is_open()) { - return helper::unexpected{ fmt::format("File '{}' couldn't be opened!", file.string()) }; + return helper::unexpected>{ std::make_pair( + fmt::format("File '{}' couldn't be opened!", file.string()), ParseError::OpenError + ) }; } std::stringstream result; result << file_stream.rdbuf(); - return try_parse_json(result.str()); + file_stream.close(); + + if (file_stream.fail()) { + return helper::unexpected>{ std::make_pair( + fmt::format("Couldn't read from file '{}'", file.string()), ParseError::ReadError + ) }; + } + + auto parse_result = try_parse_json(result.str()); + if (not parse_result.has_value()) { + return helper::unexpected>{ + std::make_pair(std::move(parse_result.error()), ParseError::FormatError) + }; + } + + return parse_result.value(); } template diff --git a/src/lobby/credentials/secret.cpp b/src/lobby/credentials/secret.cpp index 25306098..301e19cb 100644 --- a/src/lobby/credentials/secret.cpp +++ b/src/lobby/credentials/secret.cpp @@ -381,7 +381,8 @@ namespace { auto result = json::try_parse_json_file(file); if (not result.has_value()) { - return helper::unexpected{ result.error() }; + auto [error, _] = result.error(); + return helper::unexpected{ error }; } return result.value(); diff --git a/src/manager/settings_manager.cpp b/src/manager/settings_manager.cpp index cdc1af99..6115da53 100644 --- a/src/manager/settings_manager.cpp +++ b/src/manager/settings_manager.cpp @@ -17,7 +17,9 @@ SettingsManager::SettingsManager() { if (result.has_value()) { m_settings = result.value(); } else { - spdlog::error("unable to load settings from \"{}\": {}", settings_filename, result.error()); + auto [error, error_type] = result.error(); + + spdlog::error("unable to load settings from \"{}\": {}", settings_filename, error); spdlog::warn("applying default settings"); m_settings = { @@ -28,7 +30,10 @@ SettingsManager::SettingsManager() { .api_url = std::nullopt } }; - //TODO(Totto): save the file, if it doesn't exist, if it has an error, just leave it there + //save the default file, only if it doesn't exist, if it has an error, just leave it there + if (error_type == json::ParseError::OpenError) { + this->save(); + } } }