From 099f664ce65c7b825b9cc6e79178725d34b10a21 Mon Sep 17 00:00:00 2001 From: Yonas Habteab Date: Fri, 8 Mar 2024 10:16:33 +0100 Subject: [PATCH] `ConfigObjectUtility#CreateObject()`: Use `Defer` for config path cleanup --- lib/remote/configobjectutility.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/remote/configobjectutility.cpp b/lib/remote/configobjectutility.cpp index 9b5cf88b5..60268f6e1 100644 --- a/lib/remote/configobjectutility.cpp +++ b/lib/remote/configobjectutility.cpp @@ -7,6 +7,7 @@ #include "config/configitem.hpp" #include "base/atomic-file.hpp" #include "base/configwriter.hpp" +#include "base/defer.hpp" #include "base/exception.hpp" #include "base/dependencygraph.hpp" #include "base/tlsutility.hpp" @@ -204,6 +205,12 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full AtomicFile::Write(path, 0644, config); + // Remove the just created config file in all the error cases and if the object creation + // succeeds the deferred callback will be cancelled. + Defer removeConfigPath([&path]{ + Utility::Remove(path); + }); + std::unique_ptr expr = ConfigCompiler::CompileFile(path, String(), "_api"); try { @@ -227,8 +234,6 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full Log(LogNotice, "ConfigObjectUtility") << "Failed to commit config item '" << fullName << "'. Aborting and removing config path '" << path << "'."; - Utility::Remove(path); - for (const boost::exception_ptr& ex : upq.GetExceptions()) { errors->Add(DiagnosticInformation(ex, false)); @@ -250,8 +255,6 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full Log(LogNotice, "ConfigObjectUtility") << "Failed to activate config object '" << fullName << "'. Aborting and removing config path '" << path << "'."; - Utility::Remove(path); - for (const boost::exception_ptr& ex : upq.GetExceptions()) { errors->Add(DiagnosticInformation(ex, false)); @@ -275,16 +278,16 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full ConfigObject::Ptr obj = ctype->GetObject(fullName); if (obj) { + // Object is successfully created and activated, so don't remove its config. + removeConfigPath.Cancel(); + Log(LogInformation, "ConfigObjectUtility") << "Created and activated object '" << fullName << "' of type '" << type->GetName() << "'."; } else { Log(LogNotice, "ConfigObjectUtility") << "Object '" << fullName << "' was not created but ignored due to errors."; } - } catch (const std::exception& ex) { - Utility::Remove(path); - if (errors) errors->Add(DiagnosticInformation(ex, false));