diff options
author | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2024-04-23 12:15:21 +0200 |
---|---|---|
committer | Paul Cristian Sarbu <paul.cristian.sarbu@huawei.com> | 2024-04-23 17:34:17 +0200 |
commit | 1269e6040f6f35b541a17a6519c6bae907b27148 (patch) | |
tree | c100332d525184471a139e4d3b9d3f76ef38dec6 | |
parent | cb0a1d3e92d5b11effdf91779d49e1bed4a7c083 (diff) | |
download | justbuild-1269e6040f6f35b541a17a6519c6bae907b27148.tar.gz |
just-mr: Make outer non-trivial async map consumers noexcept
For setup and update subcommands, the consumer lambdas for their
respective async maps are non-trivial (i.e., do more than keeping
the map values) and operate on ungaurded JSON objects, thus it is
better to guard them against any uncaught exceptions.
-rw-r--r-- | src/other_tools/just_mr/setup.cpp | 102 | ||||
-rw-r--r-- | src/other_tools/just_mr/update.cpp | 34 |
2 files changed, 85 insertions, 51 deletions
diff --git a/src/other_tools/just_mr/setup.cpp b/src/other_tools/just_mr/setup.cpp index 5ec71a59..0479d0e5 100644 --- a/src/other_tools/just_mr/setup.cpp +++ b/src/other_tools/just_mr/setup.cpp @@ -17,6 +17,7 @@ #include <atomic> #include <condition_variable> #include <cstddef> +#include <exception> #include <thread> #include "nlohmann/json.hpp" @@ -291,55 +292,68 @@ auto MultiRepoSetup(std::shared_ptr<Configuration> const& config, setup_repos, main, interactive, - multi_repo_tool_name](auto const& values) { - // set the initial setup repositories - nlohmann::json mr_repos{}; - for (auto const& repo : setup_repos->to_setup) { - auto i = static_cast<std::size_t>( - &repo - &setup_repos->to_setup[0]); // get index - mr_repos[repo] = *values[i]; - } - // populate ALT_DIRS - constexpr auto err_msg_format = - "While performing {} {}:\nWhile populating fields for " - "repository {}:\nExpected value for key \"{}\" to be a " - "string, but found {}"; - for (auto const& repo : setup_repos->to_include) { - auto desc = repos->Get(repo, Expression::none_t{}); - if (desc.IsNotNull()) { - if (not((main and (repo == *main)) and interactive)) { - for (auto const& key : kAltDirs) { - auto val = desc->Get(key, Expression::none_t{}); - if (val.IsNotNull()) { - // we expect a string - if (not val->IsString()) { - Logger::Log( - LogLevel::Error, - err_msg_format, - multi_repo_tool_name, - interactive ? "setup-env" : "setup", - repo, - key, - val->ToString()); - failed = true; - return; - } - if (not((main and - (val->String() == *main)) and - interactive)) { - mr_repos[repo][key] = - mr_repos[val->String()] - ["workspace_root"]; + multi_repo_tool_name](auto const& values) noexcept { + try { + // set the initial setup repositories + nlohmann::json mr_repos{}; + for (auto const& repo : setup_repos->to_setup) { + auto i = static_cast<std::size_t>( + &repo - &setup_repos->to_setup[0]); // get index + mr_repos[repo] = *values[i]; + } + // populate ALT_DIRS + constexpr auto err_msg_format = + "While performing {} {}:\nWhile populating fields for " + "repository {}:\nExpected value for key \"{}\" to be a " + "string, but found {}"; + for (auto const& repo : setup_repos->to_include) { + auto desc = repos->Get(repo, Expression::none_t{}); + if (desc.IsNotNull()) { + if (not((main and (repo == *main)) and + interactive)) { + for (auto const& key : kAltDirs) { + auto val = + desc->Get(key, Expression::none_t{}); + if (val.IsNotNull()) { + // we expect a string + if (not val->IsString()) { + Logger::Log(LogLevel::Error, + err_msg_format, + multi_repo_tool_name, + interactive + ? "setup-env" + : "setup", + repo, + key, + val->ToString()); + failed = true; + return; + } + if (not((main and + (val->String() == *main)) and + interactive)) { + mr_repos[repo][key] = + mr_repos[val->String()] + ["workspace_root"]; + } + // otherwise, continue } - // otherwise, continue } } } } - } - // retain only the repos we need - for (auto const& repo : setup_repos->to_include) { - mr_config["repositories"][repo] = mr_repos[repo]; + // retain only the repos we need + for (auto const& repo : setup_repos->to_include) { + mr_config["repositories"][repo] = mr_repos[repo]; + } + } catch (std::exception const& ex) { + Logger::Log(LogLevel::Error, + "While performing {} {}:\nPopulating the " + "configuration failed with:\n{}", + multi_repo_tool_name, + interactive ? "setup-env" : "setup", + ex.what()); + failed = true; } }, [&failed, interactive, multi_repo_tool_name](auto const& msg, diff --git a/src/other_tools/just_mr/update.cpp b/src/other_tools/just_mr/update.cpp index 8d34de01..38fac998 100644 --- a/src/other_tools/just_mr/update.cpp +++ b/src/other_tools/just_mr/update.cpp @@ -14,8 +14,12 @@ #include "src/other_tools/just_mr/update.hpp" +#include <atomic> +#include <condition_variable> #include <cstddef> +#include <exception> #include <filesystem> +#include <thread> #include "fmt/core.h" #include "nlohmann/json.hpp" @@ -233,13 +237,29 @@ auto MultiRepoUpdate(std::shared_ptr<Configuration> const& config, git_update_map.ConsumeAfterKeysReady( &ts, repos_to_update, - [&mr_config, repos_to_update_names = update_args.repos_to_update]( - auto const& values) { - for (auto const& repo_name : repos_to_update_names) { - auto i = static_cast<std::size_t>( - &repo_name - &repos_to_update_names[0]); // get index - mr_config["repositories"][repo_name]["repository"] - ["commit"] = *values[i]; + [&failed, + &mr_config, + repos_to_update_names = update_args.repos_to_update, + multi_repo_tool_name](auto const& values) noexcept { + try { + for (auto const& repo_name : repos_to_update_names) { + auto i = static_cast<std::size_t>( + &repo_name - + &repos_to_update_names[0]); // get index + // we know "repository" is a map for repo_name, so + // field "commit" is here either overwritten or set if + // missing; either way, this should always work + mr_config["repositories"][repo_name]["repository"] + ["commit"] = *values[i]; + } + } catch (std::exception const& ex) { + Logger::Log( + LogLevel::Error, + "While performing {} update:\nUpdating configuration " + "fields failed with:\n{}", + multi_repo_tool_name, + ex.what()); + failed = true; } }, [&failed, &multi_repo_tool_name](auto const& msg, bool fatal) { |