aboutsummaryrefslogtreecommitdiff
path: root/src/zen/cmds/projectstore_cmd.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-09-05 13:02:27 +0200
committerGitHub Enterprise <[email protected]>2025-09-05 13:02:27 +0200
commit45b0307d42b22e04cee63467a8fdb898a2d8d552 (patch)
tree905b3eb62af89269be5b15f4c407d900ce86f7f3 /src/zen/cmds/projectstore_cmd.cpp
parentAvoid mutating executable paths when copying files during full service instal... (diff)
downloadarchived-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.cpp275
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