From e57adc94c19d792f1123f06af023348e7d98e0b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Wed, 12 Jun 2024 06:49:28 +0200 Subject: [PATCH] Handle exceptions when parsing replay `JSON` --- include/libdnf5/base/goal_elements.hpp | 4 +++- libdnf5/base/goal.cpp | 23 +++++++++++++++++++---- libdnf5/base/goal_elements.cpp | 2 ++ libdnf5/base/log_event.cpp | 3 +++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/include/libdnf5/base/goal_elements.hpp b/include/libdnf5/base/goal_elements.hpp index 54d17cf8f..a38a5802c 100644 --- a/include/libdnf5/base/goal_elements.hpp +++ b/include/libdnf5/base/goal_elements.hpp @@ -121,7 +121,8 @@ enum class GoalProblem : uint32_t { MODULE_CANNOT_SWITH_STREAMS = (1 << 21), /// Error when transaction contains additional unexpected elements. /// Used when replaying transactions. - EXTRA = (1 << 22) + EXTRA = (1 << 22), + MALFORMED = (1 << 23) }; /// Types of Goal actions @@ -144,6 +145,7 @@ enum class GoalAction { ENABLE, DISABLE, RESET, + REPLAY_PARSE, REPLAY_INSTALL, REPLAY_REMOVE, REPLAY_UPGRADE, diff --git a/libdnf5/base/goal.cpp b/libdnf5/base/goal.cpp index 342207fc6..6415d0bdd 100644 --- a/libdnf5/base/goal.cpp +++ b/libdnf5/base/goal.cpp @@ -573,6 +573,9 @@ GoalProblem Goal::Impl::add_specs_to_goal(base::Transaction & transaction) { case GoalAction::RESET: { libdnf_throw_assertion("Unsupported action \"RESET\""); } + case GoalAction::REPLAY_PARSE: { + libdnf_throw_assertion("Unsupported action \"REPLAY PARSE\""); + } case GoalAction::REPLAY_INSTALL: { libdnf_throw_assertion("Unsupported action \"REPLAY INSTALL\""); } @@ -661,10 +664,22 @@ GoalProblem Goal::Impl::add_serialized_transaction_to_goal(base::Transaction & t auto & [replay_path, settings] = *serialized_transaction; utils::fs::File replay_file(replay_path, "r"); - auto replay_location = replay_path.remove_filename(); - auto replay = transaction::parse_transaction_replay(replay_file.read()); - - return add_replay_to_goal(transaction, replay, settings, replay_location); + auto replay_location = replay_path; + replay_location.remove_filename(); + try { + auto replay = transaction::parse_transaction_replay(replay_file.read()); + return add_replay_to_goal(transaction, replay, settings, replay_location); + } catch (const libdnf5::transaction::TransactionReplayError & ex) { + transaction.p_impl->add_resolve_log( + GoalAction::REPLAY_PARSE, + libdnf5::GoalProblem::MALFORMED, + settings, + libdnf5::transaction::TransactionItemType::PACKAGE, + replay_path, + {ex.what()}, + libdnf5::Logger::Level::ERROR); + return libdnf5::GoalProblem::MALFORMED; + } } static std::set query_to_vec_of_nevra_str(const libdnf5::rpm::PackageQuery & query) { diff --git a/libdnf5/base/goal_elements.cpp b/libdnf5/base/goal_elements.cpp index dcc00b99d..46455801a 100644 --- a/libdnf5/base/goal_elements.cpp +++ b/libdnf5/base/goal_elements.cpp @@ -380,6 +380,8 @@ std::string goal_action_to_string(GoalAction action) { return _("Disable"); case GoalAction::RESET: return _("Reset"); + case GoalAction::REPLAY_PARSE: + return _("Parse serialized transaction"); case GoalAction::REPLAY_INSTALL: return _("Install action"); case GoalAction::REPLAY_REMOVE: diff --git a/libdnf5/base/log_event.cpp b/libdnf5/base/log_event.cpp index b3693263a..15a29cecd 100644 --- a/libdnf5/base/log_event.cpp +++ b/libdnf5/base/log_event.cpp @@ -337,6 +337,9 @@ std::string LogEvent::to_string( *spec, *additional_data.begin())); } + case GoalProblem::MALFORMED: { + return ret.append(utils::sformat(_("Cannot parse file: '{0}': {1}.\n"), *spec, *additional_data.begin())); + } } return ret; }