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/projectstore_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/projectstore_cmd.cpp')
| -rw-r--r-- | src/zen/cmds/projectstore_cmd.cpp | 275 |
1 files changed, 109 insertions, 166 deletions
diff --git a/src/zen/cmds/projectstore_cmd.cpp b/src/zen/cmds/projectstore_cmd.cpp index 5f0f52f7c..11c915e9a 100644 --- a/src/zen/cmds/projectstore_cmd.cpp +++ b/src/zen/cmds/projectstore_cmd.cpp @@ -149,16 +149,6 @@ namespace { } } - class AsyncJobError : public std::runtime_error - { - public: - using _Mybase = runtime_error; - - AsyncJobError(const std::string& Message, int ReturnCode) : _Mybase(Message), m_ReturnCode(ReturnCode) {} - - const int m_ReturnCode = 0; - }; - void ExecuteAsyncOperation(HttpClient& Http, std::string_view Url, IoBuffer&& Payload, bool PlainProgress) { signal(SIGINT, SignalCallbackHandler); @@ -265,11 +255,11 @@ namespace { int ReturnCode = StatusObject["ReturnCode"].AsInt32(-1); if (!AbortReason.empty()) { - throw AsyncJobError(std::string(AbortReason), ReturnCode); + throw ErrorWithReturnCode(std::string(AbortReason), ReturnCode); } else { - throw AsyncJobError("Aborted", ReturnCode); + throw ErrorWithReturnCode("Aborted", ReturnCode); } break; } @@ -564,21 +554,21 @@ DropProjectCommand::~DropProjectCommand() { } -int +void DropProjectCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions); if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } HttpClient Http(m_HostName); @@ -586,7 +576,7 @@ DropProjectCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg m_ProjectName = ResolveProject(Http, m_ProjectName); if (m_ProjectName.empty()) { - return 1; + throw std::runtime_error(fmt::format("Can't find project '{}'", m_ProjectName)); } if (m_OplogName.empty()) @@ -605,7 +595,6 @@ DropProjectCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg else { Result.ThrowError("delete project failed"sv); - return 1; } } } @@ -614,7 +603,7 @@ DropProjectCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg m_OplogName = ResolveOplog(Http, m_ProjectName, m_OplogName); if (m_OplogName.empty()) { - return 1; + throw std::runtime_error(fmt::format("Can't find oplog in project '{}'", m_OplogName, m_ProjectName)); } if (m_DryRun) { @@ -633,12 +622,9 @@ DropProjectCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg else { Result.ThrowError("delete oplog failed"sv); - return 1; } } } - - return 0; } /////////////////////////////////////// @@ -657,26 +643,26 @@ ProjectInfoCommand::~ProjectInfoCommand() { } -int +void ProjectInfoCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions); if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } if (!m_OplogName.empty() && m_ProjectName.empty()) { - throw OptionParseException("an oplog can't be specified without also specifying a project"); + throw OptionParseException("'--project' is required", m_Options.help()); } HttpClient Http(m_HostName); @@ -692,7 +678,7 @@ ProjectInfoCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg m_ProjectName = ResolveProject(Http, m_ProjectName); if (m_ProjectName.empty()) { - return 1; + throw std::runtime_error("Unable to resolve project"); } Url = fmt::format("/prj/{}", m_ProjectName); @@ -703,13 +689,13 @@ ProjectInfoCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg m_ProjectName = ResolveProject(Http, m_ProjectName); if (m_ProjectName.empty()) { - return 1; + throw std::runtime_error("Unable to resolve project"); } m_OplogName = ResolveOplog(Http, m_ProjectName, m_OplogName); if (m_OplogName.empty()) { - return 1; + throw std::runtime_error("Unable to resolve oplog"); } Url = fmt::format("/prj/{}/oplog/{}", m_ProjectName, m_OplogName); @@ -719,12 +705,10 @@ ProjectInfoCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg if (HttpClient::Response Result = Http.Get(Url, HttpClient::Accept(ZenContentType::kJSON))) { ZEN_CONSOLE("{}", Result.ToText()); - return 0; } else { Result.ThrowError("failed to fetch info"sv); - return 1; } } @@ -745,7 +729,7 @@ CreateProjectCommand::CreateProjectCommand() CreateProjectCommand::~CreateProjectCommand() = default; -int +void CreateProjectCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions); @@ -754,19 +738,19 @@ CreateProjectCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** a if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } if (m_ProjectId.empty()) { - throw OptionParseException("Project name must be given"); + throw OptionParseException("'--project' is required", m_Options.help()); } HttpClient Http(m_HostName); @@ -777,8 +761,7 @@ CreateProjectCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** a { if (HttpClient::Response Result = Http.Get(Url, HttpClient::Accept(ZenContentType::kJSON))) { - ZEN_CONSOLE_ERROR("Project already exists.\n{}", Result.ToText()); - return 1; + throw std::runtime_error(fmt::format("Project already exists.\n{}", Result.ToText())); } } @@ -793,12 +776,10 @@ CreateProjectCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** a : Http.Post(Url, Payload, HttpClient::Accept(ZenContentType::kText))) { ZEN_CONSOLE("{}", Result); - return 0; } else { Result.ThrowError("failed to create project"sv); - return 1; } } @@ -817,7 +798,7 @@ CreateOplogCommand::CreateOplogCommand() CreateOplogCommand::~CreateOplogCommand() = default; -int +void CreateOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions); @@ -826,31 +807,31 @@ CreateOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } if (m_ProjectId.empty()) { - throw OptionParseException("project name must be specified"); + throw OptionParseException("'--project' is required", m_Options.help()); } HttpClient Http(m_HostName); m_ProjectId = ResolveProject(Http, m_ProjectId); if (m_ProjectId.empty()) { - return 1; + throw std::runtime_error("Project can not be found"); } if (m_OplogId.empty()) { - throw OptionParseException("oplog name must be specified"); + throw OptionParseException("'--oplog' is required", m_Options.help()); } std::string Url = fmt::format("/prj/{}/oplog/{}", m_ProjectId, m_OplogId); @@ -858,8 +839,7 @@ CreateOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg { if (HttpClient::Response Result = Http.Get(Url, HttpClient::Accept(ZenContentType::kJSON))) { - ZEN_CONSOLE("Oplog already exists.\n{}", Result.ToText()); - return 1; + throw std::runtime_error(fmt::format("Oplog already exists.\n{}", Result.ToText())); } } @@ -873,12 +853,10 @@ CreateOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg : Http.Post(Url, OplogPayload, HttpClient::Accept(ZenContentType::kText))) { ZEN_CONSOLE("{}", Result); - return 0; } else { Result.ThrowError("failed to create oplog"sv); - return 1; } } @@ -1014,7 +992,7 @@ ExportOplogCommand::~ExportOplogCommand() { } -int +void ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { using namespace std::literals; @@ -1023,32 +1001,32 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } if (m_ProjectName.empty()) { - throw OptionParseException("project name must be specified"); + throw OptionParseException("'--project' is required", m_Options.help()); } HttpClient Http(m_HostName); m_ProjectName = ResolveProject(Http, m_ProjectName); if (m_ProjectName.empty()) { - return 1; + throw std::runtime_error("Project can not be found"); } m_OplogName = ResolveOplog(Http, m_ProjectName, m_OplogName); if (m_OplogName.empty()) { - return 1; + throw std::runtime_error("Oplog can not be found"); } size_t TargetCount = 0; @@ -1060,19 +1038,23 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg { if (TargetCount == 0) { - throw OptionParseException("an export target must be specified"); + throw OptionParseException("'--cloud', '--builds', '--zen' or '--file' is required", m_Options.help()); } else { - throw OptionParseException("a single export target must be specified"); + throw OptionParseException("'--cloud', '--builds', '--zen' or '--file' are conflicting", m_Options.help()); } } if (!m_CloudUrl.empty()) { - if (m_JupiterNamespace.empty() || m_JupiterBucket.empty()) + if (m_JupiterNamespace.empty()) { - throw OptionParseException("Options for cloud target are missing"); + throw OptionParseException("'--namespace' is required", m_Options.help()); + } + if (m_JupiterBucket.empty()) + { + throw OptionParseException("'--bucket' is required", m_Options.help()); } if (m_CloudKey.empty()) { @@ -1087,19 +1069,21 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg { if (m_JupiterNamespace.empty()) { - throw OptionParseException("Namespace for builds target it missing"); + throw OptionParseException("'--namespace' is required", m_Options.help()); } if (m_JupiterNamespace.empty() || m_JupiterBucket.empty()) { - throw OptionParseException("Bucket for builds target it missing"); + throw OptionParseException("'--bucket' is required", m_Options.help()); } if (m_BuildsMetadataPath.empty() && m_BuildsMetadata.empty()) { - throw OptionParseException("Options for builds target metadata are missing"); + throw OptionParseException("'--metadata' or --'metadata-path' is required", m_Options.help()); } if (!m_BuildsMetadataPath.empty() && !m_BuildsMetadata.empty()) { - throw OptionParseException("Conflicting options for builds target metadata"); + throw OptionParseException( + fmt::format("'--metadata' ('{}') conflicts with --'metadata-path' ('{}')", m_BuildsMetadata, m_BuildsMetadataPath), + m_Options.help()); } if (m_BuildsId.empty()) { @@ -1141,7 +1125,6 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg if (!Result) { Result.ThrowError("failed deleting existing zen remote oplog"sv); - return 1; } CreateOplog = true; } @@ -1153,7 +1136,6 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg else { Result.ThrowError("failed checking zen remote oplog"sv); - return 1; } if (CreateOplog) @@ -1162,7 +1144,6 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg if (HttpClient::Response Result = TargetHttp.Post(Url); !Result) { Result.ThrowError("failed creating zen remote oplog"sv); - return 1; } } } @@ -1341,36 +1322,24 @@ ExportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg ZEN_CONSOLE("Saving oplog '{}/{}' from '{}' to {}", m_ProjectName, m_OplogName, m_HostName, TargetDescription); - try + if (m_Async) { - if (m_Async) + if (HttpClient::Response Result = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", m_ProjectName, m_OplogName), + std::move(Payload), + HttpClient::Accept(ZenContentType::kJSON)); + Result) { - if (HttpClient::Response Result = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", m_ProjectName, m_OplogName), - std::move(Payload), - HttpClient::Accept(ZenContentType::kJSON)); - Result) - { - ZEN_CONSOLE("{}", Result.ToText()); - } - else - { - Result.ThrowError("failed requesting loading oplog export"sv); - } + ZEN_CONSOLE("{}", Result.ToText()); } else { - ExecuteAsyncOperation(Http, - fmt::format("/prj/{}/oplog/{}/rpc", m_ProjectName, m_OplogName), - std::move(Payload), - m_PlainProgress); + Result.ThrowError("failed requesting loading oplog export"sv); } } - catch (const AsyncJobError& Ex) + else { - ZEN_CONSOLE_ERROR("Oplog export failed: '{}'", Ex.what()); - return Ex.m_ReturnCode; + ExecuteAsyncOperation(Http, fmt::format("/prj/{}/oplog/{}/rpc", m_ProjectName, m_OplogName), std::move(Payload), m_PlainProgress); } - return 0; } //////////////////////////// @@ -1462,7 +1431,7 @@ ImportOplogCommand::~ImportOplogCommand() { } -int +void ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { using namespace std::literals; @@ -1471,31 +1440,31 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } if (m_ProjectName.empty()) { - throw OptionParseException("Project name must be given"); + throw OptionParseException("'--project' is required", m_Options.help()); } if (m_OplogName.empty()) { - throw OptionParseException("Oplog name must be given"); + throw OptionParseException("'--oplog' is required", m_Options.help()); } HttpClient Http(m_HostName); m_ProjectName = ResolveProject(Http, m_ProjectName); if (m_ProjectName.empty()) { - return 1; + throw std::runtime_error("Project can not be found"); } size_t TargetCount = 0; @@ -1503,20 +1472,24 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg TargetCount += m_BuildsUrl.empty() ? 0 : 1; TargetCount += m_ZenUrl.empty() ? 0 : 1; TargetCount += m_FileDirectoryPath.empty() ? 0 : 1; - if (TargetCount != 1) + if (TargetCount == 0) { - throw OptionParseException("Provide one source only"); + throw OptionParseException("'--cloud', '--builds', '--zen' or '--file' is required", m_Options.help()); + } + else if (TargetCount > 1) + { + throw OptionParseException("'--cloud', '--builds', '--zen' or '--file' are conflicting", m_Options.help()); } if (!m_CloudUrl.empty()) { if (m_JupiterNamespace.empty()) { - throw OptionParseException("Namespace option for cloud source is missing"); + throw OptionParseException("--'namespace' is required", m_Options.help()); } if (m_JupiterBucket.empty()) { - throw OptionParseException("Bucket option for cloud source is missing"); + throw OptionParseException("--'bucket' is required", m_Options.help()); } if (m_CloudKey.empty()) { @@ -1531,15 +1504,15 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg { if (m_JupiterNamespace.empty()) { - throw OptionParseException("Namespace option for builds source is missing"); + throw OptionParseException("'--namespace' is required", m_Options.help()); } if (m_JupiterBucket.empty()) { - throw OptionParseException("Bucket option for builds source is missing"); + throw OptionParseException("'--bucket' is required", m_Options.help()); } if (m_BuildsId.empty()) { - throw OptionParseException("Build id option for builds source is missing"); + throw OptionParseException("'--build-id' is required", m_Options.help()); } } @@ -1577,7 +1550,6 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg else if (!IsHttpSuccessCode(Result.StatusCode)) { Result.ThrowError("failed checking oplog"sv); - return 1; } if (CreateOplog) @@ -1591,7 +1563,6 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg if (HttpClient::Response Result = Http.Post(Url, OplogPayload); !Result) { Result.ThrowError("failed creating oplog"sv); - return 1; } } @@ -1688,36 +1659,24 @@ ImportOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg ZEN_CONSOLE("Loading oplog '{}/{}' from '{}' to {}", m_ProjectName, m_OplogName, SourceDescription, m_HostName); - try + if (m_Async) { - if (m_Async) + if (HttpClient::Response Result = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", m_ProjectName, m_OplogName), + std::move(Payload), + HttpClient::Accept(ZenContentType::kJSON)); + Result) { - if (HttpClient::Response Result = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", m_ProjectName, m_OplogName), - std::move(Payload), - HttpClient::Accept(ZenContentType::kJSON)); - Result) - { - ZEN_CONSOLE("{}", Result.ToText()); - } - else - { - Result.ThrowError("failed requesting loading oplog import"sv); - } + ZEN_CONSOLE("{}", Result.ToText()); } else { - ExecuteAsyncOperation(Http, - fmt::format("/prj/{}/oplog/{}/rpc", m_ProjectName, m_OplogName), - std::move(Payload), - m_PlainProgress); + Result.ThrowError("failed requesting loading oplog import"sv); } } - catch (const AsyncJobError& Ex) + else { - ZEN_CONSOLE_ERROR("Oplog export failed: '{}'", Ex.what()); - return Ex.m_ReturnCode; + ExecuteAsyncOperation(Http, fmt::format("/prj/{}/oplog/{}/rpc", m_ProjectName, m_OplogName), std::move(Payload), m_PlainProgress); } - return 0; } //////////////////////////// @@ -1736,7 +1695,7 @@ SnapshotOplogCommand::~SnapshotOplogCommand() { } -int +void SnapshotOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { using namespace std::literals; @@ -1745,34 +1704,33 @@ SnapshotOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** a if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } HttpClient Http(m_HostName); if (m_ProjectName.empty()) { - throw OptionParseException("Project name must be given"); - return 1; + throw OptionParseException("'--project' is required", m_Options.help()); } m_ProjectName = ResolveProject(Http, m_ProjectName); if (m_ProjectName.empty()) { - return 1; + throw std::runtime_error("Project can not be found"); } m_OplogName = ResolveOplog(Http, m_ProjectName, m_OplogName); if (m_OplogName.empty()) { - return 1; + throw std::runtime_error("Oplog can not be found"); } IoBuffer Payload = MakeCbObjectPayload([&](CbObjectWriter& Writer) { Writer.AddString("method"sv, "snapshot"sv); }); @@ -1782,12 +1740,10 @@ SnapshotOplogCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** a Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", m_ProjectName, m_OplogName), Payload, HttpClient::Accept(ZenContentType::kJSON))) { ZEN_CONSOLE("{}", Result); - return 0; } else { Result.ThrowError("failed to create project"sv); - return 1; } } @@ -1803,33 +1759,31 @@ ProjectStatsCommand::~ProjectStatsCommand() { } -int +void ProjectStatsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions); if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } HttpClient Http(m_HostName); if (HttpClient::Response Result = Http.Get("/stats/prj", HttpClient::Accept(ZenContentType::kJSON))) { ZEN_CONSOLE("{}", Result.ToText()); - return 0; } else { Result.ThrowError("failed to get project stats"sv); - return 1; } } @@ -1857,21 +1811,21 @@ ProjectOpDetailsCommand::~ProjectOpDetailsCommand() { } -int +void ProjectOpDetailsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions); if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } HttpClient Http(m_HostName); @@ -1879,13 +1833,13 @@ ProjectOpDetailsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char* m_ProjectName = ResolveProject(Http, m_ProjectName); if (m_ProjectName.empty()) { - return 1; + throw std::runtime_error("Project can not be found"); } m_OplogName = ResolveOplog(Http, m_ProjectName, m_OplogName); if (m_OplogName.empty()) { - return 1; + throw std::runtime_error("Oplog can not be found"); } ExtendableStringBuilder<128> Url; @@ -1915,12 +1869,10 @@ ProjectOpDetailsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char* {"csv", m_CSV ? "true" : "false"}})) { ZEN_CONSOLE("{}", Result.ToText()); - return 0; } else { Result.ThrowError("failed to get project details"sv); - return 1; } } @@ -1974,21 +1926,21 @@ OplogMirrorCommand::~OplogMirrorCommand() { } -int +void OplogMirrorCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions); if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } HttpClient Http(m_HostName); @@ -1996,18 +1948,18 @@ OplogMirrorCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg m_ProjectName = ResolveProject(Http, m_ProjectName); if (m_ProjectName.empty()) { - return 1; + throw std::runtime_error("Project can not be found"); } m_OplogName = ResolveOplog(Http, m_ProjectName, m_OplogName); if (m_OplogName.empty()) { - return 1; + throw std::runtime_error("Oplog can not be found"); } if (m_MirrorRootPath.empty()) { - throw OptionParseException("a target path must be specified"); + throw OptionParseException("'--target' is required", m_Options.help()); } Oid ChunkIdFilter = Oid::Zero; @@ -2016,7 +1968,7 @@ OplogMirrorCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg ChunkIdFilter = Oid::TryFromHexString(m_ChunkIdFilter); if (ChunkIdFilter == Oid::Zero) { - throw OptionParseException("chunkid must be an Oid hex string"); + throw OptionParseException(fmt::format("'--chunk' ('{}') is malformed", m_ChunkIdFilter), m_Options.help()); } } @@ -2206,25 +2158,20 @@ OplogMirrorCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** arg if (AbortFlag) { - // Error has already been reported by async code - return 1; + throw std::runtime_error("Failed top mirror oplog"); } } else { - ZEN_CONSOLE_ERROR("Unknown format response to oplog entries request"); + throw std::runtime_error("Unknown format response to oplog entries request"); } } else { Response.ThrowError("oplog entries fetch failed"); - - return 1; } ZEN_CONSOLE("mirrored {} files from {} oplog entries successfully", FileCount.load(), OplogEntryCount); - - return 0; } //////////////////////////// @@ -2244,21 +2191,21 @@ OplogValidateCommand::~OplogValidateCommand() { } -int +void OplogValidateCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions); if (!ParseOptions(argc, argv)) { - return 0; + return; } m_HostName = ResolveTargetHostSpec(m_HostName); if (m_HostName.empty()) { - throw OptionParseException("unable to resolve server specification"); + throw OptionParseException("Unable to resolve server specification", m_Options.help()); } HttpClient Http(m_HostName); @@ -2266,13 +2213,13 @@ OplogValidateCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** a m_ProjectName = ResolveProject(Http, m_ProjectName); if (m_ProjectName.empty()) { - return 1; + throw std::runtime_error("Project can not be found"); } m_OplogName = ResolveOplog(Http, m_ProjectName, m_OplogName); if (m_OplogName.empty()) { - return 1; + throw std::runtime_error("Oplog can not be found"); } std::string Url = fmt::format("/prj/{}/oplog/{}/validate", m_ProjectName, m_OplogName); @@ -2280,15 +2227,11 @@ OplogValidateCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** a if (HttpClient::Response Result = Http.Post(Url, HttpClient::Accept(ZenContentType::kJSON))) { ZEN_CONSOLE("{}", Result.ToText()); - return 0; } else { Result.ThrowError("failed to get validate project oplog"sv); - return 1; } - - return 0; } } // namespace zen |