diff options
| author | Dan Engelbrecht <[email protected]> | 2025-09-05 13:02:27 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-09-05 13:02:27 +0200 |
| commit | 45b0307d42b22e04cee63467a8fdb898a2d8d552 (patch) | |
| tree | 905b3eb62af89269be5b15f4c407d900ce86f7f3 /src/zen/cmds/service_cmd.cpp | |
| parent | Avoid mutating executable paths when copying files during full service instal... (diff) | |
| download | archived-zen-45b0307d42b22e04cee63467a8fdb898a2d8d552.tar.xz archived-zen-45b0307d42b22e04cee63467a8fdb898a2d8d552.zip | |
refactor zen command return value handling (#487)
- Improvement: Use consistent language for command line argument parsing errors
- Improvement: Changed zen command parsing errors to output help first and error last to make it easier to spot the error
- Improvement: Refactor zen command return codes to conform to valid Linux range (0-255)
kSuccess = 0,
kOtherError = 1,
kBadInput = 2,
kOutOfMemory = 16,
kOutOfDisk = 17,
kAssertError = 70,
kHttpOtherClientError = 80,
kHttpCantConnectError = 81,
kHttpNotFound = 66, // NotFound(404)
kHttpUnauthorized = 77, // Unauthorized(401),
kHttpSLLError = 82,
kHttpForbidden = 83, // Forbidden(403)
kHttpTimeout = 84, // RequestTimeout(408)
kHttpConflict = 85, // Conflict(409)
kHttpNoHost = 86,
kHttpOtherServerError = 90,
kHttpInternalServerError = 91, // InternalServerError(500)
kHttpServiceUnavailable = 69, // ServiceUnavailable(503)
kHttpBadGateway = 92, // BadGateway(502)
kHttpGatewayTimeout = 93, // GatewayTimeout(504)
Diffstat (limited to 'src/zen/cmds/service_cmd.cpp')
| -rw-r--r-- | src/zen/cmds/service_cmd.cpp | 136 |
1 files changed, 56 insertions, 80 deletions
diff --git a/src/zen/cmds/service_cmd.cpp b/src/zen/cmds/service_cmd.cpp index 398bbfc83..cf3a0bcd0 100644 --- a/src/zen/cmds/service_cmd.cpp +++ b/src/zen/cmds/service_cmd.cpp @@ -52,7 +52,7 @@ namespace { return fRet; } - int WinRelaunchElevated() + void WinRelaunchElevated() { TCHAR CurrentDir[4096]; GetCurrentDirectory(4096, CurrentDir); @@ -75,27 +75,26 @@ namespace { shExInfo.nShow = SW_SHOW; shExInfo.hInstApp = 0; - DWORD ReturnCode = 1; + DWORD ProcessReturnCode = 1; if (ShellExecuteEx(&shExInfo)) { WaitForSingleObject(shExInfo.hProcess, INFINITE); - GetExitCodeProcess(shExInfo.hProcess, &ReturnCode); + GetExitCodeProcess(shExInfo.hProcess, &ProcessReturnCode); CloseHandle(shExInfo.hProcess); - if (ReturnCode == 0) + if (ProcessReturnCode == 0) { ZEN_CONSOLE("Elevated execution completed successfully."); } else { - ZEN_CONSOLE("Elevated execution completed unsuccessfully, return code: '{}'.", ReturnCode); + throw ErrorWithReturnCode(fmt::format("Elevated execution completed unsuccessfully, return code: '{}'.", ProcessReturnCode), + (int)ProcessReturnCode); } } else { - ZEN_CONSOLE("Failed to run elevated, operation did not complete."); - ReturnCode = DWORD(-1); + ThrowLastError("Failed to run elevated, operation did not complete"); } - return (int)ReturnCode; } #else // ZEN_PLATFORM_WINDOWS @@ -104,25 +103,23 @@ namespace { #endif // ZEN_PLATFORM_WINDOWS - int RunElevated(bool AllowElevation) + void RunElevated(bool AllowElevation) { #if ZEN_PLATFORM_WINDOWS if (AllowElevation) { - return WinRelaunchElevated(); + WinRelaunchElevated(); } else { - ZEN_CONSOLE( + throw std::runtime_error(fmt::format( "This command requires elevated priviliges. Run command with elevated priviliges or add '--allow-elevation' command line " - "option."); - return 1; + "option.")); } #endif // ZEN_PLATFORM_WINDOWS #if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC ZEN_UNUSED(AllowElevation); - ZEN_CONSOLE("This command requires elevated priviliges. Run the command with `sudo`"); - return 1; + throw std::runtime_error(fmt::format("This command requires elevated priviliges. Run the command with `sudo`")); #endif // ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC } @@ -295,11 +292,9 @@ enum class ServiceStatusReturnCode UnknownError }; -int +void ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { - ZEN_UNUSED(GlobalOptions); - using namespace std::literals; std::vector<char*> SubCommandArguments; @@ -307,17 +302,17 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) int ParentCommandArgCount = GetSubCommand(m_Options, argc, argv, m_SubCommands, SubOption, SubCommandArguments); if (!ParseOptions(ParentCommandArgCount, argv)) { - return 0; + return; } if (SubOption == nullptr) { - throw zen::OptionParseException("command verb is missing"); + throw OptionParseException("'verb' option is required", m_Options.help()); } if (!ParseOptions(*SubOption, gsl::narrow<int>(SubCommandArguments.size()), SubCommandArguments.data())) { - return 0; + return; } if (SubOption == &m_StatusOptions) @@ -326,18 +321,15 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) std::error_code Ec = QueryInstalledService(m_ServiceName, Info); if (Ec) { - ZEN_CONSOLE("Can't get information about service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); - return gsl::narrow<int>(ServiceStatusReturnCode::UnknownError); + throw std::runtime_error(fmt::format("Can't get information about service '{}'. Reason: '{}'", m_ServiceName, Ec.message())); } if (Info.Status == ServiceStatus::NotInstalled) { - ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); - return gsl::narrow<int>(ServiceStatusReturnCode::NotInstalled); + throw std::runtime_error(fmt::format("Service '{}' is not installed", m_ServiceName)); } else if (Info.Status != ServiceStatus::Running) { - ZEN_CONSOLE("Service '{}' is not running", m_ServiceName); - return gsl::narrow<int>(ServiceStatusReturnCode::NotRunning); + throw std::runtime_error(fmt::format("Service '{}' is not running", m_ServiceName)); } else { @@ -349,7 +341,8 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { if (!IsElevated()) { - return RunElevated(m_AllowElevation); + RunElevated(m_AllowElevation); + return; } ServiceInfo Info; @@ -363,12 +356,10 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) Ec = StopService(m_ServiceName); if (Ec) { - ZEN_CONSOLE("Failed to stop service '{}' using '{}'. Reason: '{}'", - m_ServiceName, - m_ServerExecutable, - Ec.message()); - - return 1; + throw std::runtime_error(fmt::format("Failed to stop service '{}' using '{}'. Reason: '{}'", + m_ServiceName, + m_ServerExecutable, + Ec.message())); } int Timeout = 30000; // Wait up to 30 seconds for the service to fully stop before uninstalling @@ -377,8 +368,7 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) Ec = QueryInstalledService(m_ServiceName, Info); if (Ec) { - ZEN_CONSOLE("Failed to wait for service to stop: '{}'", Ec.message()); - return 1; + throw std::runtime_error(fmt::format("Failed to wait for service to stop: '{}'", Ec.message())); } if (Info.Status == ServiceStatus::Stopped) @@ -392,26 +382,23 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (Info.Status != ServiceStatus::Stopped) { - ZEN_CONSOLE("Timed out waiting for service to stop"); - return 1; + throw std::runtime_error("Timed out waiting for service to stop"); } } Ec = UninstallService(m_ServiceName); if (Ec) { - ZEN_CONSOLE("Failed to uninstall running service '{}' using '{}'. Reason: '{}'", - m_ServiceName, - m_ServerExecutable, - Ec.message()); - - return 1; + throw std::runtime_error(fmt::format("Failed to uninstall running service '{}' using '{}'. Reason: '{}'", + m_ServiceName, + m_ServerExecutable, + Ec.message())); } } else { ZEN_CONSOLE("Service '{}' already installed:\n{}", m_ServiceName, FmtServiceInfo(Info, " ")); - return 1; + return; } } if (m_ServerExecutable.empty()) @@ -426,7 +413,7 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { if (m_InstallPath.empty()) { - throw zen::OptionParseException("--full requires --install-path to be specified"); + throw OptionParseException("'--full' requires '--install-path'", SubOption->help()); } std::filesystem::path ExePath = zen::GetRunningExecutablePath(); @@ -451,8 +438,7 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (!std::filesystem::is_directory(m_InstallPath) && !CreateDirectories(m_InstallPath)) { - ZEN_CONSOLE("Unable to create install directory '{}'", m_InstallPath); - return 1; + throw std::runtime_error(fmt::format("Unable to create install directory '{}'", m_InstallPath)); } for (const std::filesystem::path& File : FilesToCopy) @@ -461,8 +447,7 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (!CopyFile(File, Destination, {.EnableClone = false})) { - ZEN_CONSOLE("Failed to copy '{}' to '{}'", File, Destination); - return 1; + throw std::runtime_error(fmt::format("Failed to copy '{}' to '{}'", File, Destination)); } ZEN_INFO("Copied '{}' to '{}'", File, Destination); @@ -487,8 +472,8 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) }); if (Ec) { - ZEN_CONSOLE("Failed to install service '{}' using '{}' . Reason: '{}'", m_ServiceName, m_ServerExecutable, Ec.message()); - return 1; + throw std::runtime_error( + fmt::format("Failed to install service '{}' using '{}' . Reason: '{}'", m_ServiceName, m_ServerExecutable, Ec.message())); } ZEN_CONSOLE("Installed service '{}' using '{}' successfully", m_ServiceName, m_ServerExecutable); @@ -497,8 +482,7 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) Ec = StartService(m_ServiceName); if (Ec) { - ZEN_CONSOLE("Failed to start service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); - return 1; + throw std::runtime_error(fmt::format("Failed to start service '{}'. Reason: '{}'", m_ServiceName, Ec.message())); } } } @@ -509,30 +493,28 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) std::error_code Ec = QueryInstalledService(m_ServiceName, Info); if (Ec) { - ZEN_CONSOLE("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); - return 1; + throw std::runtime_error(fmt::format("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message())); } if (Info.Status == ServiceStatus::NotInstalled) { ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); - return 0; + return; } if (Info.Status != ServiceStatus::Stopped) { - ZEN_CONSOLE("Service '{}' is running, stop before uninstalling", m_ServiceName); - return 0; + throw std::runtime_error(fmt::format("Service '{}' is running, stop before uninstalling", m_ServiceName)); } if (!IsElevated()) { - return RunElevated(m_AllowElevation); + RunElevated(m_AllowElevation); + return; } Ec = UninstallService(m_ServiceName); if (Ec) { - ZEN_CONSOLE("Failed to uninstall service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); - return 1; + throw std::runtime_error(fmt::format("Failed to uninstall service '{}'. Reason: '{}'", m_ServiceName, Ec.message())); } ZEN_CONSOLE("Uninstalled service {} successfully", m_ServiceName); } @@ -543,30 +525,28 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) std::error_code Ec = QueryInstalledService(m_ServiceName, Info); if (Ec) { - ZEN_CONSOLE("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); - return 1; + throw std::runtime_error(fmt::format("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message())); } if (Info.Status == ServiceStatus::NotInstalled) { - ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); - return 1; + throw std::runtime_error(fmt::format("Service '{}' is not installed", m_ServiceName)); } if (Info.Status != ServiceStatus::Stopped) { ZEN_CONSOLE("Service '{}' is already running", m_ServiceName); - return 1; + return; } if (!IsElevated()) { - return RunElevated(m_AllowElevation); + RunElevated(m_AllowElevation); + return; } Ec = StartService(m_ServiceName); if (Ec) { - ZEN_CONSOLE("Failed to start service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); - return 1; + throw std::runtime_error(fmt::format("Failed to start service '{}'. Reason: '{}'", m_ServiceName, Ec.message())); } ZEN_CONSOLE("Started service '{}' successfully", m_ServiceName); } @@ -577,35 +557,31 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) std::error_code Ec = QueryInstalledService(m_ServiceName, Info); if (Ec) { - ZEN_CONSOLE("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); - return 1; + throw std::runtime_error(fmt::format("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message())); } if (Info.Status == ServiceStatus::NotInstalled) { - ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); - return 1; + throw std::runtime_error(fmt::format("Service '{}' is not installed", m_ServiceName)); } if (Info.Status != ServiceStatus::Running) { ZEN_CONSOLE("Service '{}' is not running", m_ServiceName); - return 1; + return; } if (!IsElevated()) { - return RunElevated(m_AllowElevation); + RunElevated(m_AllowElevation); + return; } Ec = StopService(m_ServiceName); if (Ec) { - ZEN_CONSOLE("Failed to stop service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); - return 1; + throw std::runtime_error(fmt::format("Failed to stop service '{}'. Reason: '{}'", m_ServiceName, Ec.message())); } ZEN_CONSOLE("Stopped service '{}' successfully", m_ServiceName); } - - return 0; } } // namespace zen |