aboutsummaryrefslogtreecommitdiff
path: root/src
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
parentAvoid mutating executable paths when copying files during full service instal... (diff)
downloadzen-45b0307d42b22e04cee63467a8fdb898a2d8d552.tar.xz
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')
-rw-r--r--src/zen/cmds/admin_cmd.cpp260
-rw-r--r--src/zen/cmds/admin_cmd.h16
-rw-r--r--src/zen/cmds/bench_cmd.cpp6
-rw-r--r--src/zen/cmds/bench_cmd.h2
-rw-r--r--src/zen/cmds/builds_cmd.cpp167
-rw-r--r--src/zen/cmds/builds_cmd.h7
-rw-r--r--src/zen/cmds/cache_cmd.cpp198
-rw-r--r--src/zen/cmds/cache_cmd.h12
-rw-r--r--src/zen/cmds/copy_cmd.cpp35
-rw-r--r--src/zen/cmds/copy_cmd.h2
-rw-r--r--src/zen/cmds/dedup_cmd.cpp12
-rw-r--r--src/zen/cmds/dedup_cmd.h2
-rw-r--r--src/zen/cmds/info_cmd.cpp8
-rw-r--r--src/zen/cmds/info_cmd.h2
-rw-r--r--src/zen/cmds/print_cmd.cpp38
-rw-r--r--src/zen/cmds/print_cmd.h4
-rw-r--r--src/zen/cmds/projectstore_cmd.cpp275
-rw-r--r--src/zen/cmds/projectstore_cmd.h22
-rw-r--r--src/zen/cmds/rpcreplay_cmd.cpp123
-rw-r--r--src/zen/cmds/rpcreplay_cmd.h6
-rw-r--r--src/zen/cmds/run_cmd.cpp20
-rw-r--r--src/zen/cmds/run_cmd.h2
-rw-r--r--src/zen/cmds/serve_cmd.cpp22
-rw-r--r--src/zen/cmds/serve_cmd.h2
-rw-r--r--src/zen/cmds/service_cmd.cpp136
-rw-r--r--src/zen/cmds/service_cmd.h2
-rw-r--r--src/zen/cmds/status_cmd.cpp18
-rw-r--r--src/zen/cmds/status_cmd.h2
-rw-r--r--src/zen/cmds/top_cmd.cpp12
-rw-r--r--src/zen/cmds/top_cmd.h4
-rw-r--r--src/zen/cmds/trace_cmd.cpp32
-rw-r--r--src/zen/cmds/trace_cmd.h2
-rw-r--r--src/zen/cmds/up_cmd.cpp86
-rw-r--r--src/zen/cmds/up_cmd.h6
-rw-r--r--src/zen/cmds/version_cmd.cpp18
-rw-r--r--src/zen/cmds/version_cmd.h2
-rw-r--r--src/zen/cmds/vfs_cmd.cpp18
-rw-r--r--src/zen/cmds/vfs_cmd.h2
-rw-r--r--src/zen/cmds/wipe_cmd.cpp12
-rw-r--r--src/zen/cmds/wipe_cmd.h2
-rw-r--r--src/zen/cmds/workspaces_cmd.cpp142
-rw-r--r--src/zen/cmds/workspaces_cmd.h4
-rw-r--r--src/zen/zen.cpp204
-rw-r--r--src/zen/zen.h19
-rw-r--r--src/zencore/include/zencore/except.h4
-rw-r--r--src/zencore/include/zencore/uid.h4
-rw-r--r--src/zenserver/config.cpp81
47 files changed, 972 insertions, 1083 deletions
diff --git a/src/zen/cmds/admin_cmd.cpp b/src/zen/cmds/admin_cmd.cpp
index dca6da6c4..f0a14691b 100644
--- a/src/zen/cmds/admin_cmd.cpp
+++ b/src/zen/cmds/admin_cmd.cpp
@@ -4,6 +4,7 @@
#include <zencore/basicfile.h>
#include <zencore/filesystem.h>
+#include <zencore/fmtutils.h>
#include <zencore/logging.h>
#include <zenhttp/formatters.h>
#include <zenhttp/httpclient.h>
@@ -28,21 +29,21 @@ ScrubCommand::ScrubCommand()
ScrubCommand::~ScrubCommand() = default;
-int
+void
ScrubCommand::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);
@@ -52,19 +53,11 @@ ScrubCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (HttpClient::Response Response = Http.Post("/admin/scrub"sv, /* headers */ HttpClient::KeyValueMap{}, Params))
{
ZEN_CONSOLE("Scrub started OK: {}", Response.ToText());
-
- return 0;
- }
- else if (int StatusCode = (int)Response.StatusCode)
- {
- ZEN_CONSOLE_ERROR("Scrub start failed: {}: {} ({})", StatusCode, ReasonStringForHttpResultCode(StatusCode), Response.ToText());
}
else
{
- ZEN_CONSOLE_ERROR("Scrub start failed: {}", Response.ToText());
+ Response.ThrowError("Scrub start failed");
}
-
- return 1;
}
//////////////////////////////////////////////////////////////////////////
@@ -160,113 +153,115 @@ GcCommand::~GcCommand()
{
}
-int
+void
GcCommand::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());
}
- cpr::Parameters Params;
- Params.Add({"smallobjects", m_SmallObjects ? "true" : "false"});
+ HttpClient::KeyValueMap Params;
+ Params.Entries.insert({"smallobjects", m_SmallObjects ? "true" : "false"});
if (m_MaxCacheDuration != 0)
{
- Params.Add({"maxcacheduration", fmt::format("{}", m_MaxCacheDuration)});
+ Params.Entries.insert({"maxcacheduration", fmt::format("{}", m_MaxCacheDuration)});
}
if (m_DiskSizeSoftLimit != 0)
{
- Params.Add({"disksizesoftlimit", fmt::format("{}", m_DiskSizeSoftLimit)});
+ Params.Entries.insert({"disksizesoftlimit", fmt::format("{}", m_DiskSizeSoftLimit)});
}
- Params.Add({"skipcid", m_SkipCid ? "true" : "false"});
- Params.Add({"skipdelete", m_SkipDelete ? "true" : "false"});
+ Params.Entries.insert({"skipcid", m_SkipCid ? "true" : "false"});
+ Params.Entries.insert({"skipdelete", m_SkipDelete ? "true" : "false"});
if (m_ForceUseGCV1)
{
- throw OptionParseException("usegcv1 is deprecated and can no longer be used");
+ throw OptionParseException("'--usegcv1' is deprecated and can no longer be used", m_Options.help());
}
if (m_ForceUseGCV2)
{
- Params.Add({"forceusegcv2", "true"});
+ Params.Entries.insert({"forceusegcv2", "true"});
}
if (m_CompactBlockThreshold)
{
- Params.Add({"compactblockthreshold", fmt::format("{}", m_CompactBlockThreshold)});
+ Params.Entries.insert({"compactblockthreshold", fmt::format("{}", m_CompactBlockThreshold)});
}
IoHash LowRef = IoHash::Zero;
if (!m_ReferenceHashLow.empty())
{
if (m_ReferenceHashLow.length() != IoHash::StringLength)
{
- throw OptionParseException(fmt::format("reference-low must be a {} character hex string", IoHash::StringLength));
+ throw OptionParseException(fmt::format("'--reference-low' ('{}') is malformed, it must be a {} character hex string",
+ m_ReferenceHashLow,
+ IoHash::StringLength),
+ m_Options.help());
+ }
+ if (!IoHash::TryParse(m_ReferenceHashLow, LowRef))
+ {
+ throw OptionParseException(fmt::format("'--reference-low' ('{}') is malformed", m_ReferenceHashLow), m_Options.help());
}
- LowRef = IoHash::FromHexString(m_ReferenceHashLow);
}
IoHash HighRef = IoHash::Max;
if (!m_ReferenceHashHigh.empty())
{
if (m_ReferenceHashHigh.length() != IoHash::StringLength)
{
- throw OptionParseException(fmt::format("reference-high must be a {} character hex string", IoHash::StringLength));
+ throw OptionParseException(fmt::format("''--reference-high' ('{}') is malformed, it must be a {} character hex string",
+ m_ReferenceHashHigh,
+ IoHash::StringLength),
+ m_Options.help());
+ }
+ if (!IoHash::TryParse(m_ReferenceHashHigh, HighRef))
+ {
+ throw OptionParseException(fmt::format("'--reference-high' ('{}') is malformed", m_ReferenceHashHigh), m_Options.help());
}
- HighRef = IoHash::FromHexString(m_ReferenceHashHigh);
}
if (HighRef < LowRef)
{
- throw OptionParseException(fmt::format("invalid reference range, reference-high must be higher value than reference-low"));
+ throw OptionParseException(
+ fmt::format("'--reference-high' ('{}') is invalid, it must be a higher value than '--reference-low' ('{}')",
+ m_ReferenceHashHigh,
+ m_ReferenceHashLow),
+ m_Options.help());
}
if (!m_ReferenceHashLow.empty() || !m_ReferenceHashHigh.empty())
{
- Params.Add({"referencehashlow", LowRef.ToHexString()});
- Params.Add({"referencehashhigh", HighRef.ToHexString()});
+ Params.Entries.insert({"referencehashlow", LowRef.ToHexString()});
+ Params.Entries.insert({"referencehashhigh", HighRef.ToHexString()});
}
- Params.Add({"verbose", m_Verbose ? "true" : "false"});
- Params.Add({"singlethreaded", m_SingleThreaded ? "true" : "false"});
+ Params.Entries.insert({"verbose", m_Verbose ? "true" : "false"});
+ Params.Entries.insert({"singlethreaded", m_SingleThreaded ? "true" : "false"});
if (m_StoreCacheAttachmentMetaData)
{
- Params.Add({"storecacheattachmentmetadata", m_StoreCacheAttachmentMetaData ? "true" : "false"});
+ Params.Entries.insert({"storecacheattachmentmetadata", m_StoreCacheAttachmentMetaData ? "true" : "false"});
}
if (m_StoreProjectAttachmentMetaData)
{
- Params.Add({"storeprojectattachmentmetadata", m_StoreProjectAttachmentMetaData ? "true" : "false"});
- }
- Params.Add({"enablevalidation", m_EnableValidation ? "true" : "false"});
-
- cpr::Session Session;
- Session.SetHeader(cpr::Header{{"Accept", "application/json"}});
- Session.SetUrl({fmt::format("{}/admin/gc", m_HostName)});
- Session.SetParameters(Params);
-
- cpr::Response Result = Session.Post();
-
- if (zen::IsHttpSuccessCode(Result.status_code))
- {
- ZEN_CONSOLE("OK: {}", Result.text);
- return 0;
+ Params.Entries.insert({"storeprojectattachmentmetadata", m_StoreProjectAttachmentMetaData ? "true" : "false"});
}
+ Params.Entries.insert({"enablevalidation", m_EnableValidation ? "true" : "false"});
- if (Result.status_code)
+ HttpClient Http(m_HostName);
+ if (HttpClient::Response Response = Http.Post("/admin/gc"sv, HttpClient::Accept(HttpContentType::kJSON), Params))
{
- ZEN_CONSOLE_ERROR("GC start failed: {}: {} ({})", Result.status_code, Result.reason, Result.text);
+ ZEN_CONSOLE("OK: {}", Response.ToText());
}
else
{
- ZEN_CONSOLE_ERROR("GC start failed: {}", Result.error.message);
+ Response.ThrowError("GC start failed");
}
-
- return 1;
}
GcStatusCommand::GcStatusCommand()
@@ -280,49 +275,32 @@ GcStatusCommand::~GcStatusCommand()
{
}
-int
+void
GcStatusCommand::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());
}
- cpr::Session Session;
- Session.SetHeader(cpr::Header{{"Accept", "application/json"}});
- Session.SetUrl({fmt::format("{}/admin/gc", m_HostName)});
- if (m_Details)
- {
- Session.SetParameters({{"details", "true"}});
- }
-
- cpr::Response Result = Session.Get();
-
- if (zen::IsHttpSuccessCode(Result.status_code))
- {
- ZEN_CONSOLE("OK: {}", Result.text);
- return 0;
- }
-
- if (Result.status_code)
+ HttpClient Http(m_HostName);
+ if (HttpClient::Response Response = Http.Get("/admin/gc"sv, HttpClient::Accept(HttpContentType::kJSON)))
{
- ZEN_CONSOLE_ERROR("GC status failed: {}: {} ({})", Result.status_code, Result.reason, Result.text);
+ ZEN_CONSOLE("OK: {}", Response.ToText());
}
else
{
- ZEN_CONSOLE_ERROR("GC status failed: {}", Result.error.message);
+ Response.ThrowError("Gc status failed");
}
-
- return 1;
}
GcStopCommand::GcStopCommand()
@@ -335,48 +313,39 @@ GcStopCommand::~GcStopCommand()
{
}
-int
+void
GcStopCommand::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());
}
- cpr::Session Session;
- Session.SetUrl({fmt::format("{}/admin/gc-stop", m_HostName)});
- cpr::Response Result = Session.Post();
-
- if (static_cast<HttpResponseCode>(Result.status_code) == HttpResponseCode::Accepted)
- {
- ZEN_CONSOLE("OK: {}", "Cancel request accepted");
- return 0;
- }
- else if (zen::IsHttpSuccessCode(Result.status_code))
- {
- ZEN_CONSOLE("OK: {}", "No GC running");
- return 0;
- }
-
- if (Result.status_code)
+ HttpClient Http(m_HostName);
+ if (HttpClient::Response Response = Http.Post("/admin/gc-stop"sv, HttpClient::Accept(HttpContentType::kJSON)))
{
- ZEN_CONSOLE_ERROR("GC status failed: {}: {} ({})", Result.status_code, Result.reason, Result.text);
+ if (Response.StatusCode == HttpResponseCode::Accepted)
+ {
+ ZEN_CONSOLE("OK: {}", "Cancel request accepted");
+ }
+ else
+ {
+ ZEN_CONSOLE("OK: {}", "No GC running");
+ }
}
else
{
- ZEN_CONSOLE_ERROR("GC status failed: {}", Result.error.message);
+ Response.ThrowError("Gc stop failed");
}
-
- return 1;
}
////////////////////////////////////////////
@@ -391,7 +360,7 @@ JobCommand::JobCommand()
JobCommand::~JobCommand() = default;
-int
+void
JobCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
@@ -400,14 +369,14 @@ JobCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
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);
@@ -416,8 +385,7 @@ JobCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (m_JobId == 0)
{
- throw OptionParseException("Job id must be given");
- return 1;
+ throw OptionParseException("'--jobid' is required", m_Options.help());
}
}
std::string Url = m_JobId != 0 ? fmt::format("/admin/jobs/{}", m_JobId) : "/admin/jobs";
@@ -431,7 +399,6 @@ JobCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
else
{
Result.ThrowError("failed cancelling job"sv);
- return 1;
}
}
else if (HttpClient::Response Result = Http.Get(Url, HttpClient::Accept(ZenContentType::kJSON)))
@@ -441,10 +408,7 @@ JobCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
else
{
Result.ThrowError("failed fetching job info"sv);
- return 1;
}
-
- return 0;
}
////////////////////////////////////////////
@@ -479,7 +443,7 @@ LoggingCommand::LoggingCommand()
LoggingCommand::~LoggingCommand() = default;
-int
+void
LoggingCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
@@ -488,14 +452,14 @@ LoggingCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
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);
@@ -514,8 +478,8 @@ LoggingCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
else
{
- ZEN_CONSOLE_ERROR("Invalid value for parameter 'cache-write-log'. Use 'enable' or 'disable'");
- return 1;
+ throw OptionParseException(fmt::format("'--cache-write-log' ('{}') is invalid, use 'enable' or 'disable'", m_CacheWriteLog),
+ m_Options.help());
}
}
@@ -531,8 +495,8 @@ LoggingCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
else
{
- ZEN_CONSOLE_ERROR("Invalid value for parameter 'cache-access-log'. Use 'enable' or 'disable'");
- return 1;
+ throw OptionParseException(fmt::format("'--cache-access-log' ('{}') is invalid, use 'enable' or 'disable'", m_CacheAccessLog),
+ m_Options.help());
}
}
@@ -548,49 +512,37 @@ LoggingCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ZEN_CONSOLE("{}", Result.ToText());
const CbObject LogsResponse = Result.AsObject();
- auto CopyLog = [](std::string_view SourceName, std::string_view SourcePath, std::string_view TargetPath) -> bool {
+ auto CopyLog = [](std::string_view SourceName, std::string_view SourcePath, std::string_view TargetPath) {
if (SourcePath.empty())
{
- ZEN_CONSOLE_ERROR("Failed to retrieve {} log path", SourceName);
- return false;
+ throw std::runtime_error(fmt::format("Failed to retrieve {} log path", SourceName));
}
if (!CopyFile(SourcePath, TargetPath, {}))
{
- ZEN_CONSOLE_ERROR("Failed to copy {} log file {} to output file '{}'", SourceName, SourcePath, TargetPath);
- return false;
+ throw std::runtime_error(
+ fmt::format("Failed to copy {} log file {} to output file '{}'", SourceName, SourcePath, TargetPath));
}
- return true;
};
if (!m_ServerLogTarget.empty())
{
- if (!CopyLog("server", LogsResponse["Logfile"].AsString(), m_ServerLogTarget))
- {
- return 1;
- }
+ CopyLog("server", LogsResponse["Logfile"].AsString(), m_ServerLogTarget);
}
if (!m_CacheLogTarget.empty())
{
- if (!CopyLog("cache", LogsResponse["cache"].AsObjectView()["Logfile"].AsString(), m_CacheLogTarget))
- {
- return 1;
- }
+ CopyLog("cache", LogsResponse["cache"].AsObjectView()["Logfile"].AsString(), m_CacheLogTarget);
}
if (!m_HttpLogTarget.empty())
{
- if (!CopyLog("http", LogsResponse["http"].AsObjectView()["Logfile"].AsString(), m_HttpLogTarget))
- {
- return 1;
- }
+ CopyLog("http", LogsResponse["http"].AsObjectView()["Logfile"].AsString(), m_HttpLogTarget);
}
}
else
{
Result.ThrowError("failed fetching log info"sv);
- return 1;
}
- return 0;
+ return;
}
if (HttpClient::Response Result = Http.Post("/admin/logs", HttpClient::KeyValueMap{}, Parameters))
{
@@ -599,10 +551,7 @@ LoggingCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
else
{
Result.ThrowError("failed setting log info"sv);
- return 1;
}
-
- return 0;
}
//////////////////////////////////////////////////////////////////////////
@@ -615,21 +564,21 @@ FlushCommand::FlushCommand()
FlushCommand::~FlushCommand() = default;
-int
+void
FlushCommand::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());
}
zen::HttpClient Http(m_HostName);
@@ -638,18 +587,12 @@ FlushCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_CONSOLE("OK: {}", Response.ToText());
- return 0;
- }
- else if (int StatusCode = (int)Response.StatusCode)
- {
- ZEN_CONSOLE_ERROR("Flush failed: {}: {} ({})", StatusCode, ReasonStringForHttpResultCode(StatusCode), Response.ToText());
+ return;
}
else
{
- ZEN_CONSOLE_ERROR("Flush failed: {}", Response.ToText());
+ Response.ThrowError("Flush failed");
}
-
- return 1;
}
//////////////////////////////////////////////////////////////////////////
@@ -693,29 +636,29 @@ TryCopy(const std::filesystem::path& Source, const std::filesystem::path& Target
return CopyFile(Source, Target, Options);
}
-int
+void
CopyStateCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
if (m_DataPath.empty())
{
- throw OptionParseException("data path must be given");
+ throw OptionParseException("'--data-path' is required", m_Options.help());
}
if (!IsDir(m_DataPath))
{
- throw OptionParseException("data path must exist");
+ throw std::runtime_error(fmt::format("'--data-path' '{}' must exist", m_DataPath));
}
if (m_TargetPath.empty())
{
- throw OptionParseException("target path must be given");
+ throw OptionParseException("'--target-path' is required", m_Options.help());
}
std::filesystem::path RootManifestPath = m_DataPath / "root_manifest";
@@ -723,7 +666,8 @@ CopyStateCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (!TryCopy(RootManifestPath, TargetRootManifestPath))
{
- throw OptionParseException("data path is invalid, missing root_manifest");
+ throw std::runtime_error(
+ fmt::format("'--data-path' ('{}') is invalid, missing root_manifest at '{}'", m_DataPath, RootManifestPath));
}
std::filesystem::path CachePath = m_DataPath / "cache";
@@ -828,8 +772,6 @@ CopyStateCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
}
}
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/admin_cmd.h b/src/zen/cmds/admin_cmd.h
index c593b2cac..4f97b7ad4 100644
--- a/src/zen/cmds/admin_cmd.h
+++ b/src/zen/cmds/admin_cmd.h
@@ -16,7 +16,7 @@ public:
ScrubCommand();
~ScrubCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -35,7 +35,7 @@ public:
GcCommand();
~GcCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -64,7 +64,7 @@ public:
GcStatusCommand();
~GcStatusCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -79,7 +79,7 @@ public:
GcStopCommand();
~GcStopCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -95,7 +95,7 @@ public:
JobCommand();
~JobCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -113,7 +113,7 @@ public:
LoggingCommand();
~LoggingCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -135,7 +135,7 @@ public:
FlushCommand();
~FlushCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -151,7 +151,7 @@ public:
CopyStateCommand();
~CopyStateCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/bench_cmd.cpp b/src/zen/cmds/bench_cmd.cpp
index d904a51f6..b9c45a328 100644
--- a/src/zen/cmds/bench_cmd.cpp
+++ b/src/zen/cmds/bench_cmd.cpp
@@ -25,14 +25,14 @@ BenchCommand::BenchCommand()
BenchCommand::~BenchCommand() = default;
-int
+void
BenchCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
#if ZEN_PLATFORM_WINDOWS
@@ -97,7 +97,7 @@ BenchCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
#endif
- return 0;
+ return;
}
} // namespace zen
diff --git a/src/zen/cmds/bench_cmd.h b/src/zen/cmds/bench_cmd.h
index 29d7fcc08..ed123be75 100644
--- a/src/zen/cmds/bench_cmd.h
+++ b/src/zen/cmds/bench_cmd.h
@@ -12,7 +12,7 @@ public:
BenchCommand();
~BenchCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
virtual ZenCmdCategory& CommandCategory() const override { return g_UtilitiesCategory; }
diff --git a/src/zen/cmds/builds_cmd.cpp b/src/zen/cmds/builds_cmd.cpp
index 2c6b8e50e..d858fa328 100644
--- a/src/zen/cmds/builds_cmd.cpp
+++ b/src/zen/cmds/builds_cmd.cpp
@@ -10472,7 +10472,7 @@ BuildsCommand::BuildsCommand()
BuildsCommand::~BuildsCommand() = default;
-int
+void
BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
@@ -10489,17 +10489,17 @@ BuildsCommand::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;
}
std::filesystem::path SystemRootDir;
@@ -10522,19 +10522,22 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (!m_Host.empty())
{
- throw zen::OptionParseException(fmt::format("host is not compatible with the url option\n{}", SubOption->help()));
+ throw OptionParseException(fmt::format("'--host' ('{}') conflicts with '--url' ('{}')", m_Host, m_Url), SubOption->help());
}
if (!m_Bucket.empty())
{
- throw zen::OptionParseException(fmt::format("bucket is not compatible with the url option\n{}", SubOption->help()));
+ throw OptionParseException(fmt::format("'--bucket' ('{}') conflicts with '--url' ('{}')", m_Bucket, m_Url),
+ SubOption->help());
}
if (!m_BuildId.empty())
{
- throw zen::OptionParseException(fmt::format("buildid is not compatible with the url option\n{}", SubOption->help()));
+ throw OptionParseException(fmt::format("'--buildid' ('{}') conflicts with '--url' ('{}')", m_BuildId, m_Url),
+ SubOption->help());
}
if (!ParseCloudUrl(m_Url, m_Host, m_Namespace, m_Bucket, m_BuildId))
{
- throw zen::OptionParseException(fmt::format("url does not match the Cloud Artifact URL format\n{}", SubOption->help()));
+ throw OptionParseException("'--url' ('{}') is malformed, it does not match the Cloud Artifact URL format",
+ SubOption->help());
}
}
@@ -10542,21 +10545,22 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (!m_StoragePath.empty())
{
- throw zen::OptionParseException(
- fmt::format("host/url/override-host is not compatible with the storage-path option\n{}", SubOption->help()));
+ throw OptionParseException(
+ fmt::format("'--storage-path' ('{}') conflicts with '--host'/'--url'/'--override-host' options", m_StoragePath),
+ SubOption->help());
}
if (RequireNamespace && m_Namespace.empty())
{
- throw zen::OptionParseException(fmt::format("namespace option is required for this storage option\n{}", SubOption->help()));
+ throw OptionParseException("'--namespace' is required", SubOption->help());
}
if (RequireBucket && m_Bucket.empty())
{
- throw zen::OptionParseException(fmt::format("bucket option is required for this storage option\n{}", SubOption->help()));
+ throw OptionParseException("'--bucket' is required", SubOption->help());
}
}
else if (m_StoragePath.empty())
{
- throw zen::OptionParseException(fmt::format("At least one storage option is required\n{}", SubOption->help()));
+ throw OptionParseException("'--host', '--url', '--override-host' or '--storage-path' is required", SubOption->help());
}
MakeSafeAbsolutePathÍnPlace(m_StoragePath);
};
@@ -10594,11 +10598,11 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
.EncryptionIV = AesIV128Bit::FromString(m_EncryptionIV)};
if (!AuthMgrConfig.EncryptionKey.IsValid())
{
- throw zen::OptionParseException("Invalid AES encryption key");
+ throw OptionParseException(fmt::format("'--encryption-aes-key' ('{}') is malformed", m_EncryptionKey), SubOption->help());
}
if (!AuthMgrConfig.EncryptionIV.IsValid())
{
- throw zen::OptionParseException("Invalid AES initialization vector");
+ throw OptionParseException(fmt::format("'--encryption-aes-iv' ('{}') is malformed", m_EncryptionIV), SubOption->help());
}
Auth = AuthMgr::Create(AuthMgrConfig);
}
@@ -10701,7 +10705,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
auto ParseOutputOptions = [&]() {
if (m_Verbose && m_Quiet)
{
- throw std::runtime_error("--verbose option is not compatible with --quiet option");
+ throw OptionParseException("'--verbose' conflicts with '--quiet'", SubOption->help());
}
IsVerbose = m_Verbose;
IsQuiet = m_Quiet;
@@ -10709,7 +10713,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (IsQuiet)
{
- throw std::runtime_error("--quiet option is not compatible with --log-progress option");
+ throw OptionParseException("'--quiet' conflicts with '--log-progress'", SubOption->help());
}
ProgressMode = ProgressBar::Mode::Log;
}
@@ -10717,7 +10721,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (IsQuiet)
{
- throw std::runtime_error("--quiet option is not compatible with --plain-progress option");
+ throw OptionParseException("'--quiet' conflicts with '--plain-progress'", SubOption->help());
}
ProgressMode = ProgressBar::Mode::Plain;
}
@@ -10952,7 +10956,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
else
{
- throw zen::OptionParseException(fmt::format("Storage option is missing\n{}", SubOption->help()));
+ throw OptionParseException("'--host', '--url', '--override-host' or '--storage-path' is required", SubOption->help());
}
if (!m_ZenCacheHost.empty())
{
@@ -10998,7 +11002,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
auto ParsePath = [&]() {
if (m_Path.empty())
{
- throw zen::OptionParseException(fmt::format("local-path is required\n{}", SubOption->help()));
+ throw OptionParseException("'--local-path' is required", SubOption->help());
}
MakeSafeAbsolutePathÍnPlace(m_Path);
};
@@ -11024,7 +11028,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
auto ParseDiffPath = [&]() {
if (m_DiffPath.empty())
{
- throw zen::OptionParseException(fmt::format("compare-path is required\n{}", SubOption->help()));
+ throw OptionParseException("'--compare-path' is required", SubOption->help());
}
MakeSafeAbsolutePathÍnPlace(m_DiffPath);
};
@@ -11033,13 +11037,20 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
m_BlobHash = RemoveQuotes(m_BlobHash);
if (m_BlobHash.empty())
{
- throw zen::OptionParseException(fmt::format("Blob hash string is missing\n{}", SubOption->help()));
+ throw OptionParseException("'--blob-hash' is required", SubOption->help());
+ }
+
+ if (m_BlobHash.length() != IoHash::StringLength)
+ {
+ throw OptionParseException(
+ fmt::format("'--blob-hash' ('{}') is malfomed, it must be {} characters long", m_BlobHash, IoHash::StringLength),
+ SubOption->help());
}
IoHash BlobHash;
if (!IoHash::TryParse(m_BlobHash, BlobHash))
{
- throw zen::OptionParseException(fmt::format("Blob hash string is invalid\n{}", SubOption->help()));
+ throw OptionParseException(fmt::format("'--blob-hash' ('{}') is malformed", m_BlobHash), SubOption->help());
}
return BlobHash;
@@ -11049,11 +11060,13 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
m_BuildId = RemoveQuotes(m_BuildId);
if (m_BuildId.length() != Oid::StringLength)
{
- throw zen::OptionParseException(fmt::format("Invalid build id\n{}", SubOption->help()));
+ throw OptionParseException(
+ fmt::format("'--build-id' ('{}') is malfomed, it must be {} characters long", m_BuildId, Oid::StringLength),
+ SubOption->help());
}
else if (Oid BuildId = Oid::FromHexString(m_BuildId); BuildId == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("Invalid build id\n{}", SubOption->help()));
+ throw OptionParseException(fmt::format("'--build-id' ('{}') is invalid", m_BuildId), SubOption->help());
}
else
{
@@ -11065,11 +11078,13 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
m_BuildPartId = RemoveQuotes(m_BuildPartId);
if (m_BuildPartId.length() != Oid::StringLength)
{
- throw zen::OptionParseException(fmt::format("Invalid build part id\n{}", SubOption->help()));
+ throw OptionParseException(
+ fmt::format("'--build-id' ('{}') is malformed, it must be {} characters long", m_BuildPartId, Oid::StringLength),
+ SubOption->help());
}
else if (Oid BuildPartId = Oid::FromHexString(m_BuildPartId); BuildPartId == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("Invalid build part id\n{}", SubOption->help()));
+ throw OptionParseException(fmt::format("'--build-id' ('{}') is malformed", m_BuildPartId), SubOption->help());
}
else
{
@@ -11084,7 +11099,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
BuildPartIds.push_back(Oid::TryFromHexString(RemoveQuotes(BuildPartId)));
if (BuildPartIds.back() == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("build-part-id '{}' is invalid\n{}", BuildPartId, SubOption->help()));
+ throw OptionParseException(fmt::format("'--build-part-id' ('{}') is malformed", BuildPartId), SubOption->help());
}
}
return BuildPartIds;
@@ -11097,7 +11112,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
BuildPartNames.push_back(std::string(RemoveQuotes(BuildPartName)));
if (BuildPartNames.back().empty())
{
- throw zen::OptionParseException(fmt::format("build-part-names '{}' is invalid\n{}", BuildPartName, SubOption->help()));
+ throw OptionParseException(fmt::format("'--build-part-names' ('{}') is invalid", BuildPartName), SubOption->help());
}
}
return BuildPartNames;
@@ -11108,11 +11123,13 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (m_BuildMetadataPath.empty() && m_BuildMetadata.empty())
{
- throw zen::OptionParseException(fmt::format("Options for builds target are missing\n{}", SubOption->help()));
+ throw OptionParseException("'--metadata-path' or '--metadata' is required", SubOption->help());
}
if (!m_BuildMetadataPath.empty() && !m_BuildMetadata.empty())
{
- throw zen::OptionParseException(fmt::format("Conflicting options for builds target\n{}", SubOption->help()));
+ throw OptionParseException(
+ fmt::format("'--metadata-path' ('{}') conflicts with '--metadata' ('{}')", m_BuildMetadataPath, m_BuildMetadata),
+ SubOption->help());
}
if (!m_BuildMetadataPath.empty())
@@ -11149,12 +11166,11 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (!m_BuildMetadataPath.empty())
{
- throw zen::OptionParseException(
- fmt::format("metadata-path option is only valid if creating a build\n{}", SubOption->help()));
+ throw OptionParseException("'--metadata-path' requires '--create-build'", SubOption->help());
}
if (!m_BuildMetadata.empty())
{
- throw zen::OptionParseException(fmt::format("metadata option is only valid if creating a build\n{}", SubOption->help()));
+ throw OptionParseException("'--metadata' requires '--create-build'", SubOption->help());
}
}
return {};
@@ -11220,8 +11236,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
WriteFile(ListResultPath, IoBuffer(IoBuffer::Wrap, SB.Data(), SB.Size()));
}
}
-
- return 0;
+ return;
}
if (SubOption == &m_ListOptions)
@@ -11313,8 +11328,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
WriteFile(m_ListResultPath, IoBuffer(IoBuffer::Wrap, SB.Data(), SB.Size()));
}
}
-
- return 0;
+ return;
}
if (SubOption == &m_UploadOptions)
@@ -11412,7 +11426,10 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
: 0);
}
}
- return AbortFlag ? 11 : 0;
+ if (AbortFlag)
+ {
+ throw std::runtime_error("Upload aborted");
+ }
}
if (SubOption == &m_DownloadOptions)
@@ -11446,8 +11463,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (m_PostDownloadVerify && m_PrimeCacheOnly)
{
- throw zen::OptionParseException(
- fmt::format("'cache-prime-only' option is not compatible with 'verify' option\n{}", SubOption->help()));
+ throw OptionParseException("'--cache-prime-only' conflicts with '--verify'", SubOption->help());
}
if (m_Clean && m_PrimeCacheOnly)
@@ -11480,7 +11496,10 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
m_IncludeWildcard,
m_ExcludeWildcard);
- return AbortFlag ? 11 : 0;
+ if (AbortFlag)
+ {
+ throw std::runtime_error("Download aborted");
+ }
}
if (SubOption == &m_LsOptions)
@@ -11516,7 +11535,10 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ListBuild(Storage, BuildId, BuildPartIds, BuildPartNames, m_IncludeWildcard, m_ExcludeWildcard);
- return AbortFlag ? 11 : 0;
+ if (AbortFlag)
+ {
+ throw std::runtime_error("List build aborted");
+ }
}
if (SubOption == &m_DiffOptions)
@@ -11525,7 +11547,10 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ParseDiffPath();
DiffFolders(m_Path, m_DiffPath, m_OnlyChunked);
- return AbortFlag ? 11 : 0;
+ if (AbortFlag)
+ {
+ throw std::runtime_error("Diff folders aborted");
+ }
}
if (SubOption == &m_FetchBlobOptions)
@@ -11568,7 +11593,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ValidateBlob(*Storage.BuildStorage, BuildId, BlobHash, CompressedSize, DecompressedSize);
if (AbortFlag)
{
- return 11;
+ throw std::runtime_error("Fetch blob aborted");
}
if (!IsQuiet)
{
@@ -11577,7 +11602,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
CompressedSize,
DecompressedSize);
}
- return 0;
+ return;
}
if (SubOption == &m_ValidateBuildPartOptions)
@@ -11617,7 +11642,9 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (!m_BuildPartName.empty() && !m_BuildPartId.empty())
{
- throw zen::OptionParseException(fmt::format("build-part-id conflicts with build-part-name\n{}", SubOption->help()));
+ throw OptionParseException(
+ fmt::format("'--build-part-id' ('{}') conflicts with '--build-part-name' ('{}')", m_BuildPartId, m_BuildPartName),
+ SubOption->help());
}
const Oid BuildPartId = m_BuildPartName.empty() ? Oid::Zero : ParseBuildPartId();
@@ -11626,7 +11653,10 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
DownloadStatistics DownloadStats;
ValidateBuildPart(*Storage.BuildStorage, BuildId, BuildPartId, m_BuildPartName, ValidateStats, DownloadStats);
- return AbortFlag ? 13 : 0;
+ if (AbortFlag)
+ {
+ throw std::runtime_error("Validate build part failed");
+ }
}
if (SubOption == &m_MultiTestDownloadOptions)
@@ -11659,7 +11689,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
Oid BuildId = Oid::FromHexString(RemoveQuotes(BuildIdString));
if (BuildId == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("invalid build id {}\n{}", BuildIdString, SubOption->help()));
+ throw OptionParseException(fmt::format("'--build-id' ('{}') is malformed", BuildIdString), SubOption->help());
}
DownloadFolder(Storage,
BuildId,
@@ -11678,8 +11708,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
""sv);
if (AbortFlag)
{
- ZEN_CONSOLE("Download cancelled");
- return 11;
+ throw std::runtime_error("Multitest aborted");
}
if (!IsQuiet)
{
@@ -11690,7 +11719,6 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_CONSOLE("Completed in {}", NiceTimeSpanMs(Timer.GetElapsedTimeMs()));
}
- return 0;
}
auto ParseZenProcessId = [&]() {
@@ -11706,7 +11734,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
if (!RunningProcess.IsValid())
{
- throw zen::OptionParseException(
+ throw std::runtime_error(
fmt::format("Unable to find a running instance of the zen executable '{}'", RunningExecutablePath));
}
m_ZenProcessId = RunningProcess.Pid();
@@ -11718,7 +11746,6 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ParseZenProcessId();
ZenState RunningState(m_ZenProcessId);
RunningState.StateData().Pause.store(true);
- return 0;
}
if (SubOption == &m_ResumeOptions)
@@ -11726,7 +11753,6 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ParseZenProcessId();
ZenState RunningState(m_ZenProcessId);
RunningState.StateData().Pause.store(false);
- return 0;
}
if (SubOption == &m_AbortOptions)
@@ -11734,7 +11760,6 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ParseZenProcessId();
ZenState RunningState(m_ZenProcessId);
RunningState.StateData().Abort.store(true);
- return 0;
}
if (SubOption == &m_TestOptions)
@@ -11834,8 +11859,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
true);
if (AbortFlag)
{
- ZEN_CONSOLE_ERROR("Upload failed.");
- return 11;
+ throw std::runtime_error("Test aborted. (Upload build)");
}
ZEN_CONSOLE("\nDownload Build {}, Part {} ({}) to '{}'", BuildId, BuildPartId, m_BuildPartName, DownloadPath);
@@ -11856,8 +11880,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
""sv);
if (AbortFlag)
{
- ZEN_CONSOLE_ERROR("Download failed.");
- return 11;
+ throw std::runtime_error("Test aborted. (Download build)");
}
ZEN_CONSOLE("\nRe-download Build {}, Part {} ({}) to '{}' (identical target)", BuildId, BuildPartId, m_BuildPartName, DownloadPath);
@@ -11878,8 +11901,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
""sv);
if (AbortFlag)
{
- ZEN_CONSOLE_ERROR("Re-download failed. (identical target)");
- return 11;
+ throw std::runtime_error("Test aborted. (Re-download identical target)");
}
auto ScrambleDir = [](const std::filesystem::path& Path) {
@@ -11992,8 +12014,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
""sv);
if (AbortFlag)
{
- ZEN_CONSOLE_ERROR("Re-download failed. (scrambled target)");
- return 11;
+ throw std::runtime_error("Test aborted. (Re-download scrambled target)");
}
ScrambleDir(DownloadPath);
@@ -12024,8 +12045,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
true);
if (AbortFlag)
{
- ZEN_CONSOLE_ERROR("Upload of scrambled failed.");
- return 11;
+ throw std::runtime_error("Test aborted. (Upload scrambled)");
}
ZEN_CONSOLE("\nDownload Build {}, Part {} ({}) to '{}' (original)", BuildId, BuildPartId, m_BuildPartName, DownloadPath);
@@ -12046,8 +12066,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
""sv);
if (AbortFlag)
{
- ZEN_CONSOLE_ERROR("Re-download failed.");
- return 11;
+ throw std::runtime_error("Test aborted. (Download original)");
}
ZEN_CONSOLE("\nDownload Build {}, Part {} ({}) to '{}' (scrambled)", BuildId2, BuildPartId2, m_BuildPartName, DownloadPath);
@@ -12068,8 +12087,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
""sv);
if (AbortFlag)
{
- ZEN_CONSOLE_ERROR("Re-download failed.");
- return 11;
+ throw std::runtime_error("Test aborted. (Download scrambled)");
}
ZEN_CONSOLE("\nRe-download Build {}, Part {} ({}) to '{}' (scrambled)", BuildId2, BuildPartId2, m_BuildPartName, DownloadPath);
@@ -12090,8 +12108,7 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
""sv);
if (AbortFlag)
{
- ZEN_CONSOLE_ERROR("Re-download failed.");
- return 11;
+ throw std::runtime_error("Test aborted. (Re-download scrambled)");
}
ZEN_CONSOLE("\nDownload Build {}, Part {} ({}) to '{}' (original)", BuildId, BuildPartId, m_BuildPartName, DownloadPath2);
@@ -12112,13 +12129,9 @@ BuildsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
""sv);
if (AbortFlag)
{
- ZEN_CONSOLE_ERROR("Re-download failed.");
- return 11;
+ throw std::runtime_error("Test aborted. (Download original)");
}
-
- return 0;
}
- ZEN_ASSERT(false);
}
} // namespace zen
diff --git a/src/zen/cmds/builds_cmd.h b/src/zen/cmds/builds_cmd.h
index d057d24ac..79d69b16c 100644
--- a/src/zen/cmds/builds_cmd.h
+++ b/src/zen/cmds/builds_cmd.h
@@ -13,13 +13,14 @@ namespace zen {
class BuildsCommand : public CacheStoreCommand
{
public:
- static constexpr char Name[] = "builds";
- static constexpr char Description[] = "Manage builds - list, upload, download, diff";
+ static constexpr char Name[] = "builds";
+ static constexpr char Description[] =
+ "Manage builds - list, list-namespaces, ls, upload, download, diff, fetch-blob, validate-part, pause, resume, abort";
BuildsCommand();
~BuildsCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/cache_cmd.cpp b/src/zen/cmds/cache_cmd.cpp
index 90f428b29..ea7ad79ee 100644
--- a/src/zen/cmds/cache_cmd.cpp
+++ b/src/zen/cmds/cache_cmd.cpp
@@ -70,59 +70,53 @@ DropCommand::DropCommand()
DropCommand::~DropCommand() = default;
-int
+void
DropCommand::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 zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", m_Options.help());
}
if (m_NamespaceName.empty())
{
- throw zen::OptionParseException("Drop command requires a namespace");
+ throw OptionParseException("'--namespace' is required", m_Options.help());
}
- cpr::Session Session;
+ std::string Url;
+ std::string DropDescription;
+
if (m_BucketName.empty())
{
- ZEN_CONSOLE("Dropping cache namespace '{}' from '{}'", m_NamespaceName, m_HostName);
- Session.SetUrl({fmt::format("{}/z$/{}", m_HostName, m_NamespaceName)});
+ DropDescription = fmt::format("cache namespace '{}' from '{}'", m_NamespaceName, m_HostName);
+ Url = fmt::format("/z$/{}", m_NamespaceName);
}
else
{
- ZEN_CONSOLE("Dropping cache bucket '{}/{}' from '{}'", m_NamespaceName, m_BucketName, m_HostName);
- Session.SetUrl({fmt::format("{}/z$/{}/{}", m_HostName, m_NamespaceName, m_BucketName)});
+ DropDescription = fmt::format("cache bucket '{}/{}' from '{}'", m_NamespaceName, m_BucketName, m_HostName);
+ Url = fmt::format("/z$/{}/{}", m_NamespaceName, m_BucketName);
}
- cpr::Response Result = Session.Delete();
-
- if (zen::IsHttpSuccessCode(Result.status_code))
- {
- ZEN_CONSOLE("OK: drop succeeded");
-
- return 0;
- }
+ ZEN_CONSOLE("Dropping {}", DropDescription);
- if (Result.status_code)
+ HttpClient Http(m_HostName);
+ if (HttpClient::Response Response = Http.Delete(Url))
{
- ZEN_CONSOLE_ERROR("Drop failed: {}: {} ({})", Result.status_code, Result.reason, Result.text);
+ ZEN_CONSOLE("{}", Response.ToText());
}
else
{
- ZEN_CONSOLE_ERROR("Drop failed: {}", Result.error.message);
+ Response.ThrowError(fmt::format("Failed to drop {}", DropDescription));
}
-
- return 1;
}
CacheInfoCommand::CacheInfoCommand()
@@ -144,87 +138,76 @@ CacheInfoCommand::CacheInfoCommand()
CacheInfoCommand::~CacheInfoCommand() = default;
-int
+void
CacheInfoCommand::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 zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", m_Options.help());
}
- cpr::Session Session;
- Session.SetHeader(cpr::Header{{"Accept", "application/json"}});
+ std::string Url;
if (m_HostName.empty())
{
if (!m_SizeInfoBucketNames.empty())
{
- throw zen::OptionParseException("--bucketsizes option needs a --namespace");
+ throw OptionParseException("'--bucketsizes' requires '--namespace'", m_Options.help());
}
if (m_BucketSizeInfo)
{
- throw zen::OptionParseException("--bucketsizes option needs a --namespace and a --bucket");
+ throw OptionParseException("'--bucketsize' requires '--namespace' and '--bucket'", m_Options.help());
}
ZEN_CONSOLE("Info on cache from '{}'", m_HostName);
- Session.SetUrl({fmt::format("{}/z$", m_HostName)});
+ Url = "/z$";
}
else if (m_BucketName.empty())
{
if (m_BucketSizeInfo)
{
- throw zen::OptionParseException("--bucketsizes option needs a --bucket");
+ throw OptionParseException(fmt::format("'--bucketsize' requires '--namespace' and '--bucket' ('{}')", m_BucketName),
+ m_Options.help());
}
ZEN_CONSOLE("Info on cache namespace '{}' from '{}'", m_NamespaceName, m_HostName);
- Session.SetUrl({fmt::format("{}/z$/{}", m_HostName, m_NamespaceName)});
+ Url = fmt::format("/z$/{}", m_NamespaceName);
}
else
{
if (!m_SizeInfoBucketNames.empty())
{
- throw zen::OptionParseException("--bucketsizes option can not be used together with --bucket option");
+ throw OptionParseException("'--bucketsizes' conflicts with '--bucket'", m_Options.help());
}
ZEN_CONSOLE("Info on cache bucket '{}/{}' from '{}'", m_NamespaceName, m_BucketName, m_HostName);
- Session.SetUrl({fmt::format("{}/z$/{}/{}", m_HostName, m_NamespaceName, m_BucketName)});
+ Url = fmt::format("/z$/{}/{}", m_NamespaceName, m_BucketName);
}
- cpr::Parameters Parameters;
+ HttpClient::KeyValueMap Parameters;
if (!m_SizeInfoBucketNames.empty())
{
- Parameters.Add({"bucketsizes", m_SizeInfoBucketNames});
+ Parameters.Entries.insert({"bucketsizes", m_SizeInfoBucketNames});
}
if (m_BucketSizeInfo)
{
- Parameters.Add({"bucketsize", "true"});
- }
-
- Session.SetParameters(Parameters);
- cpr::Response Result = Session.Get();
-
- if (zen::IsHttpSuccessCode(Result.status_code))
- {
- ZEN_CONSOLE("{}", Result.text);
-
- return 0;
+ Parameters.Entries.insert({"bucketsize", "true"});
}
- if (Result.status_code)
+ HttpClient Http(m_HostName);
+ if (HttpClient::Response Response = Http.Get(Url, HttpClient::Accept(ZenContentType::kJSON), Parameters))
{
- ZEN_CONSOLE_ERROR("Info failed: {}: {} ({})", Result.status_code, Result.reason, Result.text);
+ ZEN_CONSOLE("{}", Response.ToText());
}
else
{
- ZEN_CONSOLE_ERROR("Info failed: {}", Result.error.message);
+ Response.ThrowError("Info failed");
}
-
- return 1;
}
CacheStatsCommand::CacheStatsCommand()
@@ -235,46 +218,32 @@ CacheStatsCommand::CacheStatsCommand()
CacheStatsCommand::~CacheStatsCommand() = default;
-int
+void
CacheStatsCommand::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 zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", m_Options.help());
}
- cpr::Session Session;
- Session.SetUrl({fmt::format("{}/stats/z$", m_HostName)});
- Session.SetHeader(cpr::Header{{"Accept", "application/json"}});
-
- cpr::Response Result = Session.Get();
-
- if (zen::IsHttpSuccessCode(Result.status_code))
- {
- ZEN_CONSOLE("{}", Result.text);
-
- return 0;
- }
-
- if (Result.status_code)
+ HttpClient Http(m_HostName);
+ if (HttpClient::Response Response = Http.Get("/stats/z$", HttpClient::Accept(ZenContentType::kJSON)))
{
- ZEN_CONSOLE_ERROR("Info failed: {}: {} ({})", Result.status_code, Result.reason, Result.text);
+ ZEN_CONSOLE("{}", Response.ToText());
}
else
{
- ZEN_CONSOLE_ERROR("Info failed: {}", Result.error.message);
+ Response.ThrowError("Info failed");
}
-
- return 1;
}
CacheDetailsCommand::CacheDetailsCommand()
@@ -296,87 +265,82 @@ CacheDetailsCommand::CacheDetailsCommand()
CacheDetailsCommand::~CacheDetailsCommand() = default;
-int
+void
CacheDetailsCommand::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 zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", m_Options.help());
}
- cpr::Session Session;
- cpr::Parameters Parameters;
+ HttpClient::KeyValueMap Parameters;
if (m_Details)
{
- Parameters.Add({"details", "true"});
+ Parameters.Entries.insert({"details", "true"});
}
if (m_AttachmentDetails)
{
- Parameters.Add({"attachmentdetails", "true"});
+ Parameters.Entries.insert({"attachmentdetails", "true"});
}
+
+ HttpClient::KeyValueMap Headers;
if (m_CSV)
{
- Parameters.Add({"csv", "true"});
+ Parameters.Entries.insert({"csv", "true"});
}
else
{
- Session.SetHeader(cpr::Header{{"Accept", "application/json"}});
+ Headers = HttpClient::Accept(ZenContentType::kJSON);
}
+ std::string Url;
if (!m_ValueKey.empty())
{
- if (m_Namespace.empty() || m_Bucket.empty())
+ if (m_Namespace.empty())
+ {
+ throw OptionParseException("'--namespace' is required", m_Options.help());
+ }
+ if (m_Bucket.empty())
{
- throw OptionParseException("Provide namespace and bucket name");
+ throw OptionParseException("'--bucket' is required", m_Options.help());
}
- Session.SetUrl({fmt::format("{}/z$/details$/{}/{}/{}", m_HostName, m_Namespace, m_Bucket, m_ValueKey)});
+ Url = fmt::format("/z$/details$/{}/{}/{}", m_Namespace, m_Bucket, m_ValueKey);
}
else if (!m_Bucket.empty())
{
if (m_Namespace.empty())
{
- throw OptionParseException("Provide namespace name");
+ throw OptionParseException("'--namespace' is required", m_Options.help());
}
- Session.SetUrl({fmt::format("{}/z$/details$/{}/{}", m_HostName, m_Namespace, m_Bucket)});
+ Url = fmt::format("/z$/details$/{}/{}", m_Namespace, m_Bucket);
}
else if (!m_Namespace.empty())
{
- Session.SetUrl({fmt::format("{}/z$/details$/{}", m_HostName, m_Namespace)});
+ Url = fmt::format("/z$/details$/{}", m_Namespace);
}
else
{
- Session.SetUrl({fmt::format("{}/z$/details$", m_HostName)});
+ Url = "/z$/details$";
}
- Session.SetParameters(Parameters);
-
- cpr::Response Result = Session.Get();
- if (zen::IsHttpSuccessCode(Result.status_code))
- {
- ZEN_CONSOLE("{}", Result.text);
-
- return 0;
- }
-
- if (Result.status_code)
+ HttpClient Http(m_HostName);
+ if (HttpClient::Response Response = Http.Get(Url, Headers, Parameters))
{
- ZEN_CONSOLE_ERROR("Info failed: {}: {} ({})", Result.status_code, Result.reason, Result.text);
+ ZEN_CONSOLE("{}", Response.ToText());
}
else
{
- ZEN_CONSOLE_ERROR("Info failed: {}", Result.error.message);
+ Response.ThrowError("Info failed");
}
-
- return 1;
}
CacheGenerateCommand::CacheGenerateCommand()
@@ -407,21 +371,21 @@ CacheGenerateCommand::CacheGenerateCommand()
CacheGenerateCommand::~CacheGenerateCommand() = default;
-int
+void
CacheGenerateCommand::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 zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", m_Options.help());
}
if (m_MaxSize == 0 && m_MinSize == 0)
@@ -542,8 +506,6 @@ CacheGenerateCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** a
{
ZEN_INFO("Creating data, {} requests remaining", WorkLatch.Remaining());
}
-
- return 0;
}
CacheGetCommand::CacheGetCommand()
@@ -570,7 +532,7 @@ CacheGetCommand::CacheGetCommand()
CacheGetCommand::~CacheGetCommand() = default;
-int
+void
CacheGetCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
@@ -579,35 +541,35 @@ CacheGetCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
m_HostName = ResolveTargetHostSpec(m_HostName);
if (m_HostName.empty())
{
- throw zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", m_Options.help());
}
if (m_Namespace.empty())
{
- throw zen::OptionParseException("cache-get command requires a namespace");
+ throw OptionParseException("'--namespace' is required", m_Options.help());
}
if (m_Bucket.empty())
{
- throw zen::OptionParseException("cache-get command requires a bucket");
+ throw OptionParseException("'--bucket' is required", m_Options.help());
}
if (m_ValueKey.empty())
{
- throw zen::OptionParseException("cache-get command requires a value key");
+ throw OptionParseException("'--valuekey' is required", m_Options.help());
}
IoHash ValueId;
if (!IoHash::TryParse(m_ValueKey, ValueId))
{
- throw zen::OptionParseException("cache-get --valuekey option requires a valid IoHash string");
+ throw OptionParseException(fmt::format("'--value-key' ('{}') is malformed", m_ValueKey), m_Options.help());
}
IoHash AttachmentHash;
@@ -615,7 +577,7 @@ CacheGetCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (!IoHash::TryParse(m_AttachmentHash, AttachmentHash))
{
- throw zen::OptionParseException("cache-get --attachmenthash option requires a valid IoHash string");
+ throw OptionParseException(fmt::format("'--attachmenthash' ('{}') is malformed", m_AttachmentHash), m_Options.help());
}
}
@@ -681,8 +643,6 @@ CacheGetCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
Result.ThrowError("Failed to fetch data"sv);
}
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/cache_cmd.h b/src/zen/cmds/cache_cmd.h
index b8a319359..4dc05bbdc 100644
--- a/src/zen/cmds/cache_cmd.h
+++ b/src/zen/cmds/cache_cmd.h
@@ -12,7 +12,7 @@ public:
DropCommand();
~DropCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -27,7 +27,7 @@ class CacheInfoCommand : public CacheStoreCommand
public:
CacheInfoCommand();
~CacheInfoCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -44,7 +44,7 @@ class CacheStatsCommand : public CacheStoreCommand
public:
CacheStatsCommand();
~CacheStatsCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -57,7 +57,7 @@ class CacheDetailsCommand : public CacheStoreCommand
public:
CacheDetailsCommand();
~CacheDetailsCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -79,7 +79,7 @@ public:
CacheGenerateCommand();
~CacheGenerateCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -104,7 +104,7 @@ public:
CacheGetCommand();
~CacheGetCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/copy_cmd.cpp b/src/zen/cmds/copy_cmd.cpp
index 4e54f27bb..530661607 100644
--- a/src/zen/cmds/copy_cmd.cpp
+++ b/src/zen/cmds/copy_cmd.cpp
@@ -24,23 +24,23 @@ CopyCommand::CopyCommand()
CopyCommand::~CopyCommand() = default;
-int
+void
CopyCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
- if (!ZenCmdBase::ParseOptions(argc, argv))
+ if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
// Validate arguments
if (m_CopySource.empty())
- throw std::runtime_error("No source specified");
+ throw OptionParseException("'--source' is required", m_Options.help());
if (m_CopyTarget.empty())
- throw std::runtime_error("No target specified");
+ throw OptionParseException("'--target' is required", m_Options.help());
std::filesystem::path FromPath = m_CopySource;
std::filesystem::path ToPath = m_CopyTarget;
@@ -180,9 +180,7 @@ CopyCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (Visitor.FailedFileCount)
{
- ZEN_CONSOLE_ERROR("{} file copy operations FAILED", Visitor.FailedFileCount);
-
- return 1;
+ throw std::runtime_error(fmt::format("{} file copy operations FAILED", Visitor.FailedFileCount));
}
}
else
@@ -194,27 +192,16 @@ CopyCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
zen::CopyFileOptions CopyOptions;
CopyOptions.EnableClone = !m_NoClone;
- try
+ zen::CreateDirectories(ToPath.parent_path());
+ if (zen::CopyFile(FromPath, ToPath, CopyOptions))
{
- zen::CreateDirectories(ToPath.parent_path());
- if (zen::CopyFile(FromPath, ToPath, CopyOptions))
- {
- ZEN_CONSOLE("Copy completed in {}", zen::NiceTimeSpanMs(Timer.GetElapsedTimeMs()));
- }
- else
- {
- throw std::logic_error("CopyFile failed in an unexpected way");
- }
+ ZEN_CONSOLE("Copy completed in {}", zen::NiceTimeSpanMs(Timer.GetElapsedTimeMs()));
}
- catch (const std::exception& Ex)
+ else
{
- ZEN_CONSOLE_ERROR("Failed to copy '{}' to '{}': '{}'", FromPath, ToPath, Ex.what());
-
- return 1;
+ throw std::runtime_error(fmt::format("Failed to copy '{}' to '{}'", FromPath, ToPath));
}
}
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/copy_cmd.h b/src/zen/cmds/copy_cmd.h
index e9735c159..e1a5dcb82 100644
--- a/src/zen/cmds/copy_cmd.h
+++ b/src/zen/cmds/copy_cmd.h
@@ -15,7 +15,7 @@ public:
~CopyCommand();
virtual cxxopts::Options& Options() override { return m_Options; }
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual ZenCmdCategory& CommandCategory() const override { return g_UtilitiesCategory; }
private:
diff --git a/src/zen/cmds/dedup_cmd.cpp b/src/zen/cmds/dedup_cmd.cpp
index 033ac87c3..9ef50a97d 100644
--- a/src/zen/cmds/dedup_cmd.cpp
+++ b/src/zen/cmds/dedup_cmd.cpp
@@ -51,14 +51,14 @@ DedupCommand::DedupCommand()
DedupCommand::~DedupCommand() = default;
-int
+void
DedupCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
// Validate arguments
@@ -68,14 +68,12 @@ DedupCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (!SourceGood)
{
- ZEN_CONSOLE_ERROR("Source directory '{}' does not support deduplication", m_DedupSource);
- return 0;
+ throw std::runtime_error(fmt::format("Source directory '{}' does not support deduplication", m_DedupSource));
}
if (!TargetGood)
{
- ZEN_CONSOLE_ERROR("Target directory '{}' does not support deduplication", m_DedupTarget);
- return 0;
+ throw std::runtime_error(fmt::format("Target directory '{}' does not support deduplication", m_DedupTarget));
}
ZEN_CONSOLE("Performing dedup operation between {} and {}, size threshold {}",
@@ -295,8 +293,6 @@ DedupCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
ZEN_CONSOLE("Elapsed: {} Deduped: {}", zen::NiceTimeSpanMs(Timer.GetElapsedTimeMs()), zen::NiceBytes(DupeBytes));
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/dedup_cmd.h b/src/zen/cmds/dedup_cmd.h
index 2721be2b9..5b8387dd2 100644
--- a/src/zen/cmds/dedup_cmd.h
+++ b/src/zen/cmds/dedup_cmd.h
@@ -15,7 +15,7 @@ public:
~DedupCommand();
virtual cxxopts::Options& Options() override { return m_Options; }
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual ZenCmdCategory& CommandCategory() const override { return g_UtilitiesCategory; }
private:
diff --git a/src/zen/cmds/info_cmd.cpp b/src/zen/cmds/info_cmd.cpp
index 8e0b3d663..49ad022cf 100644
--- a/src/zen/cmds/info_cmd.cpp
+++ b/src/zen/cmds/info_cmd.cpp
@@ -21,21 +21,21 @@ InfoCommand::~InfoCommand()
{
}
-int
+void
InfoCommand::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);
@@ -48,8 +48,6 @@ InfoCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
Result.ThrowError(fmt::format("Failed getting info from {}", m_HostName));
}
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/info_cmd.h b/src/zen/cmds/info_cmd.h
index 9723a075b..231565bfd 100644
--- a/src/zen/cmds/info_cmd.h
+++ b/src/zen/cmds/info_cmd.h
@@ -12,7 +12,7 @@ public:
InfoCommand();
~InfoCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
// virtual ZenCmdCategory& CommandCategory() const override { return g_UtilitiesCategory; }
diff --git a/src/zen/cmds/print_cmd.cpp b/src/zen/cmds/print_cmd.cpp
index fd6d92f28..c3c11a0ea 100644
--- a/src/zen/cmds/print_cmd.cpp
+++ b/src/zen/cmds/print_cmd.cpp
@@ -55,20 +55,20 @@ PrintCommand::PrintCommand()
PrintCommand::~PrintCommand() = default;
-int
+void
PrintCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
// Validate arguments
if (m_Filename.empty())
- throw std::runtime_error("No file specified");
+ throw OptionParseException("'--source' is required", m_Options.help());
FileContents Fc;
@@ -84,9 +84,7 @@ PrintCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (Fc.ErrorCode)
{
- ZEN_CONSOLE_ERROR("Failed to read file '{}': {}", m_Filename, Fc.ErrorCode.message());
-
- return 1;
+ throw std::runtime_error(fmt::format("Failed to read file '{}': {}", m_Filename, Fc.ErrorCode.message()));
}
IoBuffer Data = Fc.Flatten();
@@ -158,11 +156,11 @@ PrintCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (FilteredResult != CbValidateError::None)
{
- ZEN_CONSOLE_ERROR("Object in package message file '{}' does not appear to be compact binary (validation error {:#x}: '{}')",
- m_Filename,
- uint32_t(FilteredResult),
- ToString(FilteredResult));
- return 1;
+ throw std::runtime_error(
+ fmt::format("Object in package message file '{}' does not appear to be compact binary (validation error {:#x}: '{}')",
+ m_Filename,
+ uint32_t(FilteredResult),
+ ToString(FilteredResult)));
}
else
{
@@ -185,18 +183,16 @@ PrintCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (FilteredResult != CbValidateError::None)
{
- ZEN_CONSOLE_ERROR("Data in file '{}' does not appear to be compact binary (validation error {:#x}: '{}')",
- m_Filename,
- uint32_t(FilteredResult),
- ToString(FilteredResult));
- return 1;
+ throw std::runtime_error(fmt::format("Data in file '{}' does not appear to be compact binary (validation error {:#x}: '{}')",
+ m_Filename,
+ uint32_t(FilteredResult),
+ ToString(FilteredResult)));
}
else
{
PrintCompactBinary(Data, m_ShowCbObjectTypeInfo);
}
}
- return 0;
}
//////////////////////////////////////////////////////////////////////////
@@ -218,20 +214,20 @@ PrintPackageCommand::~PrintPackageCommand()
{
}
-int
+void
PrintPackageCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
// Validate arguments
if (m_Filename.empty())
- throw std::runtime_error("No file specified");
+ throw OptionParseException("'--source' is required", m_Options.help());
MakeSafeAbsolutePathÍnPlace(m_Filename);
FileContents Fc = ReadFile(m_Filename);
@@ -250,8 +246,6 @@ PrintPackageCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** ar
{
ZEN_ERROR("error: malformed package?");
}
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/print_cmd.h b/src/zen/cmds/print_cmd.h
index 80729901e..6c1529b7c 100644
--- a/src/zen/cmds/print_cmd.h
+++ b/src/zen/cmds/print_cmd.h
@@ -14,7 +14,7 @@ public:
PrintCommand();
~PrintCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
virtual ZenCmdCategory& CommandCategory() const override { return g_UtilitiesCategory; }
@@ -32,7 +32,7 @@ public:
PrintPackageCommand();
~PrintPackageCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
virtual ZenCmdCategory& CommandCategory() const override { return g_UtilitiesCategory; }
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
diff --git a/src/zen/cmds/projectstore_cmd.h b/src/zen/cmds/projectstore_cmd.h
index 0d24d8529..70b336650 100644
--- a/src/zen/cmds/projectstore_cmd.h
+++ b/src/zen/cmds/projectstore_cmd.h
@@ -17,7 +17,7 @@ public:
DropProjectCommand();
~DropProjectCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -33,7 +33,7 @@ class ProjectInfoCommand : public ProjectStoreCommand
public:
ProjectInfoCommand();
~ProjectInfoCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -49,7 +49,7 @@ public:
CreateProjectCommand();
~CreateProjectCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -69,7 +69,7 @@ public:
CreateOplogCommand();
~CreateOplogCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -87,7 +87,7 @@ public:
ExportOplogCommand();
~ExportOplogCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -142,7 +142,7 @@ public:
ImportOplogCommand();
~ImportOplogCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -189,7 +189,7 @@ public:
SnapshotOplogCommand();
~SnapshotOplogCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -204,7 +204,7 @@ class ProjectStatsCommand : public ProjectStoreCommand
public:
ProjectStatsCommand();
~ProjectStatsCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -217,7 +217,7 @@ class ProjectOpDetailsCommand : public ProjectStoreCommand
public:
ProjectOpDetailsCommand();
~ProjectOpDetailsCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -237,7 +237,7 @@ class OplogMirrorCommand : public ProjectStoreCommand
public:
OplogMirrorCommand();
~OplogMirrorCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -258,7 +258,7 @@ class OplogValidateCommand : public ProjectStoreCommand
public:
OplogValidateCommand();
~OplogValidateCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/rpcreplay_cmd.cpp b/src/zen/cmds/rpcreplay_cmd.cpp
index 6c26eaf23..4e672eea5 100644
--- a/src/zen/cmds/rpcreplay_cmd.cpp
+++ b/src/zen/cmds/rpcreplay_cmd.cpp
@@ -12,6 +12,7 @@
#include <zencore/stream.h>
#include <zencore/timer.h>
#include <zencore/workthreadpool.h>
+#include <zenhttp/httpclient.h>
#include <zenhttp/httpcommon.h>
#include <zenhttp/packageformat.h>
#include <zenutil/cache/rpcrecording.h>
@@ -26,6 +27,54 @@ ZEN_THIRD_PARTY_INCLUDES_END
namespace zen {
+namespace {
+ // TODO: Convert direct use of cpr to HttpClient
+
+ std::string FormatHttpResponse(const cpr::Response& Response)
+ {
+ if (Response.error.code != cpr::ErrorCode::OK)
+ {
+ if (Response.error.message.empty())
+ {
+ return fmt::format("Request '{}' failed, error code {}", Response.url.str(), static_cast<int>(Response.error.code));
+ }
+ return fmt::format("Request '{}' failed. Reason: '{}' ({})",
+ Response.url.str(),
+ Response.error.message,
+ static_cast<int>(Response.error.code));
+ }
+
+ std::string Content;
+ if (auto It = Response.header.find("Content-Type"); It != Response.header.end())
+ {
+ zen::HttpContentType ContentType = zen::ParseContentType(It->second);
+ if (ContentType == zen::HttpContentType::kText)
+ {
+ Content = Response.text;
+ }
+ else if (ContentType == zen::HttpContentType::kJSON)
+ {
+ Content = fmt::format("\n{}", Response.text);
+ }
+ else if (!Response.text.empty())
+ {
+ Content = fmt::format("[{}]", MapContentTypeToString(ContentType));
+ }
+ }
+
+ std::string_view ResponseString = zen::ReasonStringForHttpResultCode(
+ Response.status_code == static_cast<long>(zen::HttpResponseCode::NoContent) ? static_cast<long>(zen::HttpResponseCode::OK)
+ : Response.status_code);
+ if (Content.empty())
+ {
+ return std::string(ResponseString);
+ }
+
+ return fmt::format("{}: {}", ResponseString, Content);
+ }
+
+} // namespace
+
using namespace std::literals;
RpcStartRecordingCommand::RpcStartRecordingCommand()
@@ -39,33 +88,37 @@ RpcStartRecordingCommand::RpcStartRecordingCommand()
RpcStartRecordingCommand::~RpcStartRecordingCommand() = default;
-int
+void
RpcStartRecordingCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions, argc, argv);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
m_HostName = ResolveTargetHostSpec(m_HostName);
if (m_HostName.empty())
{
- throw zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", m_Options.help());
}
if (m_RecordingPath.empty())
{
- throw zen::OptionParseException("Rpc start recording command requires a path");
+ throw OptionParseException("'--path' is required", m_Options.help());
}
- cpr::Session Session;
- Session.SetUrl(fmt::format("{}/z$/exec$/start-recording"sv, m_HostName));
- Session.SetParameters({{"path", m_RecordingPath}});
- cpr::Response Response = Session.Post();
- ZEN_CONSOLE("{}", FormatHttpResponse(Response));
- return MapHttpToCommandReturnCode(Response);
+ HttpClient Http(m_HostName);
+ if (HttpClient::Response Response =
+ Http.Post("/z$/exec$/start-recording"sv, HttpClient::KeyValueMap{}, HttpClient::KeyValueMap({{"path", m_RecordingPath}})))
+ {
+ ZEN_CONSOLE("{}", Response.ToText());
+ }
+ else
+ {
+ Response.ThrowError("Failed to start recording");
+ }
}
////////////////////////////////////////////////////
@@ -78,28 +131,32 @@ RpcStopRecordingCommand::RpcStopRecordingCommand()
RpcStopRecordingCommand::~RpcStopRecordingCommand() = default;
-int
+void
RpcStopRecordingCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions, argc, argv);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
m_HostName = ResolveTargetHostSpec(m_HostName);
if (m_HostName.empty())
{
- throw zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", m_Options.help());
}
- cpr::Session Session;
- Session.SetUrl(fmt::format("{}/z$/exec$/stop-recording"sv, m_HostName));
- cpr::Response Response = Session.Post();
- ZEN_CONSOLE("{}", FormatHttpResponse(Response));
- return MapHttpToCommandReturnCode(Response);
+ HttpClient Http(m_HostName);
+ if (HttpClient::Response Response = Http.Post("/z$/exec$/stop-recording"sv))
+ {
+ ZEN_CONSOLE("{}", Response.ToText());
+ }
+ else
+ {
+ Response.ThrowError("Failed to stop recording");
+ }
}
////////////////////////////////////////////////////
@@ -174,26 +231,26 @@ RpcReplayCommand::RpcReplayCommand()
RpcReplayCommand::~RpcReplayCommand() = default;
-int
+void
RpcReplayCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions, argc, argv);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
m_HostName = ResolveTargetHostSpec(m_HostName);
if (m_HostName.empty())
{
- throw zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", m_Options.help());
}
if (m_RecordingPath.empty())
{
- throw zen::OptionParseException("Rpc replay command requires a path");
+ throw OptionParseException("'--path' is required", m_Options.help());
}
if (!IsDir(m_RecordingPath))
@@ -207,12 +264,18 @@ RpcReplayCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (m_OnHost)
{
- cpr::Session Session;
- Session.SetUrl(fmt::format("{}/z$/exec$/replay-recording"sv, m_HostName));
- Session.SetParameters({{"path", m_RecordingPath}, {"thread-count", fmt::format("{}", m_ThreadCount)}});
- cpr::Response Response = Session.Post();
- ZEN_CONSOLE("{}", FormatHttpResponse(Response));
- return MapHttpToCommandReturnCode(Response);
+ HttpClient Http(m_HostName);
+ if (HttpClient::Response Response =
+ Http.Post("/z$/exec$/replay-recording"sv,
+ HttpClient::KeyValueMap{},
+ HttpClient::KeyValueMap({{"path", m_RecordingPath}, {"thread-count", fmt::format("{}", m_ThreadCount)}})))
+ {
+ ZEN_CONSOLE("{}", Response.ToText());
+ }
+ else
+ {
+ Response.ThrowError("Failed to start replay");
+ }
}
std::unique_ptr<cache::IRpcRequestReplayer> Replayer = cache::MakeDiskRequestReplayer(m_RecordingPath, true);
@@ -251,7 +314,7 @@ RpcReplayCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ZEN_CONSOLE("Waiting for worker processes...");
Sleep(1000);
}
- return 0;
+ return;
}
else
{
@@ -478,8 +541,6 @@ RpcReplayCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
NiceByteRate(Received, ElapsedMS),
NiceTimeSpanMs(ElapsedMS),
NiceTimeSpanMs(TotalTimer.GetElapsedTimeMs()));
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/rpcreplay_cmd.h b/src/zen/cmds/rpcreplay_cmd.h
index 42cdd4ac1..a6363b614 100644
--- a/src/zen/cmds/rpcreplay_cmd.h
+++ b/src/zen/cmds/rpcreplay_cmd.h
@@ -12,7 +12,7 @@ public:
RpcStartRecordingCommand();
~RpcStartRecordingCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -27,7 +27,7 @@ public:
RpcStopRecordingCommand();
~RpcStopRecordingCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -41,7 +41,7 @@ public:
RpcReplayCommand();
~RpcReplayCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/run_cmd.cpp b/src/zen/cmds/run_cmd.cpp
index 309b8996a..00ab16fe5 100644
--- a/src/zen/cmds/run_cmd.cpp
+++ b/src/zen/cmds/run_cmd.cpp
@@ -57,32 +57,32 @@ RunCommand::~RunCommand()
{
}
-int
+void
RunCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
- ZEN_UNUSED(GlobalOptions);
-
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
// Validate arguments
if (GlobalOptions.PassthroughArgV.empty() || GlobalOptions.PassthroughArgV[0].empty())
- throw OptionParseException("No command specified. The command to run is passed in after a double dash ('--') on the command line");
+ throw OptionParseException("No command specified. The command to run is passed in after a double dash ('--') on the command line",
+ m_Options.help());
if (m_RunCount < 0)
- throw OptionParseException("Invalid count specified");
+ throw OptionParseException(fmt::format("'--count' ('{}') is invalid", m_RunCount), m_Options.help());
if (m_RunTime < -1 || m_RunTime == 0)
- throw OptionParseException("Invalid run time specified");
+ throw OptionParseException(fmt::format("'--time' ('{}') is invalid", m_RunTime), m_Options.help());
if (m_MaxBaseDirectoryCount < 0)
- throw OptionParseException("Invalid directory count specified");
+ throw OptionParseException(fmt::format("'--max-dirs' ('{}') is invalid", m_MaxBaseDirectoryCount), m_Options.help());
if (m_RunTime > 0 && m_RunCount > 0)
- throw OptionParseException("Specify either time or count, not both");
+ throw OptionParseException(fmt::format("'--time' ('{}') conflicts with '--count' ('{}') ", m_RunTime, m_RunCount),
+ m_Options.help());
if (m_RunCount == 0)
m_RunCount = 1;
@@ -190,8 +190,6 @@ RunCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
fmt::print("run complete, no error exit code\n", m_RunCount);
}
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/run_cmd.h b/src/zen/cmds/run_cmd.h
index f6512a4e8..570a2e63a 100644
--- a/src/zen/cmds/run_cmd.h
+++ b/src/zen/cmds/run_cmd.h
@@ -12,7 +12,7 @@ public:
RunCommand();
~RunCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
virtual ZenCmdCategory& CommandCategory() const override { return g_UtilitiesCategory; }
diff --git a/src/zen/cmds/serve_cmd.cpp b/src/zen/cmds/serve_cmd.cpp
index cfaa12bc0..49389bcdf 100644
--- a/src/zen/cmds/serve_cmd.cpp
+++ b/src/zen/cmds/serve_cmd.cpp
@@ -34,19 +34,19 @@ ServeCommand::~ServeCommand()
{
}
-int
+void
ServeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
if (m_ProjectName.empty())
{
- throw zen::OptionParseException("command requires a project");
+ throw OptionParseException("'--project' is required", m_Options.help());
}
if (m_OplogName.empty())
@@ -58,18 +58,18 @@ ServeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
else
{
- throw zen::OptionParseException("command requires an oplog");
+ throw OptionParseException("'--oplog' is required", m_Options.help());
}
}
if (m_RootPath.empty())
{
- throw zen::OptionParseException("command requires a root path");
+ throw OptionParseException("'--path' is required", m_Options.help());
}
if (!IsDir(m_RootPath))
{
- throw zen::OptionParseException(fmt::format("path must exist and must be a directory: '{}'", m_RootPath));
+ throw std::runtime_error(fmt::format("'--path' ('{}') must exist and must be a directory", m_RootPath));
}
uint16_t ServerPort = 0;
@@ -95,7 +95,7 @@ ServeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_CONSOLE_ERROR("Failed to spawn server on port {}: '{}'", ServerPort, Ex.what());
- throw zen::OptionParseException("unable to resolve server specification (even after spawning server)");
+ throw std::runtime_error("Unable to resolve server specification (even after spawning server)");
}
}
else
@@ -197,8 +197,7 @@ ServeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (auto NewProjectResponse = Client.Post(ProjectUri, Project.Save()); !NewProjectResponse)
{
- // TODO: include details
- throw std::runtime_error("failed to create project");
+ NewProjectResponse.ThrowError("Failed to create project");
}
}
@@ -212,8 +211,7 @@ ServeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (auto NewOplogResponse = Client.Post(ProjectOplogUri, Oplog.Save()); !NewOplogResponse)
{
- // TODO: include details
- throw std::runtime_error("failed to create oplog");
+ NewOplogResponse.ThrowError("Failed to create oplog");
}
}
@@ -233,8 +231,6 @@ ServeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
#if ZEN_PLATFORM_WINDOWS
_getch(); // TEMPORARY HACK
#endif
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/serve_cmd.h b/src/zen/cmds/serve_cmd.h
index 007038d84..ac74981f2 100644
--- a/src/zen/cmds/serve_cmd.h
+++ b/src/zen/cmds/serve_cmd.h
@@ -14,7 +14,7 @@ public:
ServeCommand();
~ServeCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
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
diff --git a/src/zen/cmds/service_cmd.h b/src/zen/cmds/service_cmd.h
index 359e8e854..ee98620d1 100644
--- a/src/zen/cmds/service_cmd.h
+++ b/src/zen/cmds/service_cmd.h
@@ -17,7 +17,7 @@ public:
ServiceCommand();
~ServiceCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/status_cmd.cpp b/src/zen/cmds/status_cmd.cpp
index 5b172f1a5..c43f85052 100644
--- a/src/zen/cmds/status_cmd.cpp
+++ b/src/zen/cmds/status_cmd.cpp
@@ -20,14 +20,14 @@ StatusCommand::StatusCommand()
StatusCommand::~StatusCommand() = default;
-int
+void
StatusCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
uint16_t EffectivePort = 0;
@@ -35,8 +35,7 @@ StatusCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (!IsFile(m_DataDir / ".lock"))
{
- ZEN_CONSOLE_ERROR("Lock file does not exist in directory '{}'", m_DataDir);
- return 1;
+ throw std::runtime_error(fmt::format("Lock file does not exist in directory '{}'", m_DataDir));
}
CbValidateError ValidateResult = CbValidateError::None;
if (CbObject LockFileObject =
@@ -47,15 +46,14 @@ StatusCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
std::string Reason;
if (!ValidateLockFileInfo(Info, Reason))
{
- ZEN_CONSOLE_ERROR("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, Reason);
- return 1;
+ throw std::runtime_error(fmt::format("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, Reason));
}
EffectivePort = Info.EffectiveListenPort;
}
else
{
- ZEN_CONSOLE_ERROR("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, ToString(ValidateResult));
- return 1;
+ throw std::runtime_error(
+ fmt::format("Lock file in directory '{}' is malformed. Reason: '{}'", m_DataDir, ToString(ValidateResult)));
}
}
@@ -63,7 +61,7 @@ StatusCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (!State.InitializeReadOnly())
{
ZEN_CONSOLE("No Zen state found");
- return 0;
+ return;
}
ZEN_CONSOLE("{:>5} {:>6} {:>24}", "port", "pid", "session");
@@ -78,8 +76,6 @@ StatusCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ZEN_CONSOLE("{:>5} {:>6} {:>24}", Entry.EffectiveListenPort.load(), Entry.Pid.load(), SessionStringBuilder);
}
});
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/status_cmd.h b/src/zen/cmds/status_cmd.h
index 46bda9ee6..dc103a196 100644
--- a/src/zen/cmds/status_cmd.h
+++ b/src/zen/cmds/status_cmd.h
@@ -14,7 +14,7 @@ public:
StatusCommand();
~StatusCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/top_cmd.cpp b/src/zen/cmds/top_cmd.cpp
index 9794dc1c0..0e44dbbec 100644
--- a/src/zen/cmds/top_cmd.cpp
+++ b/src/zen/cmds/top_cmd.cpp
@@ -19,7 +19,7 @@ TopCommand::TopCommand()
TopCommand::~TopCommand() = default;
-int
+void
TopCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions, argc, argv);
@@ -29,7 +29,7 @@ TopCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_CONSOLE("No Zen state found");
- return 0;
+ return;
}
int n = 0;
@@ -55,8 +55,6 @@ TopCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
State.Sweep();
}
}
-
- return 0;
}
//////////////////////////////////////////////////////////////////////////
@@ -67,7 +65,7 @@ PsCommand::PsCommand()
PsCommand::~PsCommand() = default;
-int
+void
PsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions, argc, argv);
@@ -77,14 +75,12 @@ PsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_CONSOLE("No Zen state found");
- return 0;
+ return;
}
State.Snapshot([&](const ZenServerState::ZenServerEntry& Entry) {
ZEN_CONSOLE("Port {} : pid {}", Entry.EffectiveListenPort.load(), Entry.Pid.load());
});
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/top_cmd.h b/src/zen/cmds/top_cmd.h
index 83410587b..74167ecfd 100644
--- a/src/zen/cmds/top_cmd.h
+++ b/src/zen/cmds/top_cmd.h
@@ -12,7 +12,7 @@ public:
TopCommand();
~TopCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -25,7 +25,7 @@ public:
PsCommand();
~PsCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/trace_cmd.cpp b/src/zen/cmds/trace_cmd.cpp
index 85caf33b8..41a30068c 100644
--- a/src/zen/cmds/trace_cmd.cpp
+++ b/src/zen/cmds/trace_cmd.cpp
@@ -20,21 +20,21 @@ TraceCommand::TraceCommand()
TraceCommand::~TraceCommand() = default;
-int
+void
TraceCommand::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());
}
zen::HttpClient Http(m_HostName);
@@ -44,13 +44,12 @@ TraceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (zen::HttpClient::Response Response = Http.Post("/admin/trace/stop"sv))
{
ZEN_CONSOLE("OK: {}", Response.ToText());
- return 0;
}
else
{
- ZEN_CONSOLE_ERROR("trace stop failed: {}", Response.ToText());
- return 1;
+ Response.ThrowError("Trace stop failed");
}
+ return;
}
std::string StartArg;
@@ -68,26 +67,23 @@ TraceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (zen::HttpClient::Response Response = Http.Post(fmt::format("/admin/trace/start?{}"sv, StartArg)))
{
ZEN_CONSOLE("OK: {}", Response.ToText());
- return 0;
}
else
{
- ZEN_CONSOLE_ERROR("trace start failed: {}", Response.ToText());
- return 1;
+ Response.ThrowError("Trace start failed");
}
}
-
- if (zen::HttpClient::Response Response = Http.Get("/admin/trace"sv))
- {
- ZEN_CONSOLE("OK: {}", Response.ToText());
- return 0;
- }
else
{
- ZEN_CONSOLE_ERROR("trace status failed: {}", Response.ToText());
+ if (zen::HttpClient::Response Response = Http.Get("/admin/trace"sv))
+ {
+ ZEN_CONSOLE("OK: {}", Response.ToText());
+ }
+ else
+ {
+ Response.ThrowError("Trace status failed");
+ }
}
-
- return 1;
}
} // namespace zen
diff --git a/src/zen/cmds/trace_cmd.h b/src/zen/cmds/trace_cmd.h
index 404fb57a4..a6c9742b7 100644
--- a/src/zen/cmds/trace_cmd.h
+++ b/src/zen/cmds/trace_cmd.h
@@ -14,7 +14,7 @@ public:
TraceCommand();
~TraceCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/up_cmd.cpp b/src/zen/cmds/up_cmd.cpp
index 8deb6c70e..a219677df 100644
--- a/src/zen/cmds/up_cmd.cpp
+++ b/src/zen/cmds/up_cmd.cpp
@@ -31,7 +31,7 @@ UpCommand::UpCommand()
UpCommand::~UpCommand() = default;
-int
+void
UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
using namespace std::literals;
@@ -40,12 +40,12 @@ UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
if (m_ShowConsole && m_ShowLog)
{
- throw OptionParseException("--show-console can not be used in combination with --show-log");
+ throw OptionParseException("'--show-console' conficts with '--show-log'", m_Options.help());
}
{
@@ -73,7 +73,7 @@ UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
RunningEntries[0].DesiredPort,
RunningEntries[0].EffectivePort,
RunningEntries[0].Pid);
- return 0;
+ return;
}
}
}
@@ -99,20 +99,25 @@ UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (Server.IsRunning())
{
- ZEN_CONSOLE_ERROR("Zen server launch failed (timed out), terminating");
+ ZEN_CONSOLE_WARN("Zen server launch failed (timed out), terminating");
Server.Terminate();
if (!m_ShowConsole)
{
ZEN_CONSOLE("{}", Server.GetLogOutput());
}
- return 111;
+ throw std::runtime_error("Zen server launch failed (timed out), launched process was terminated");
}
- int ReturnCode = Server.Shutdown();
+ int ServerExitCode = Server.Shutdown();
if (!m_ShowConsole)
{
ZEN_CONSOLE("{}", Server.GetLogOutput());
}
- return ReturnCode;
+ if (ServerExitCode != 0)
+ {
+ throw ErrorWithReturnCode(
+ fmt::format("Zen server failed to get to a ready state and exited with return code {}", ServerExitCode),
+ ServerExitCode);
+ }
}
else
{
@@ -125,7 +130,6 @@ UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ZEN_CONSOLE("Zen server up");
}
}
- return 0;
}
//////////////////////////////////////////////////////////////////////////
@@ -139,14 +143,14 @@ AttachCommand::AttachCommand()
AttachCommand::~AttachCommand() = default;
-int
+void
AttachCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
ZenServerState Instance;
@@ -158,8 +162,7 @@ AttachCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (!IsFile(m_DataDir / ".lock"))
{
- ZEN_CONSOLE("Lock file does not exist in directory '{}'", m_DataDir);
- return 1;
+ throw std::runtime_error(fmt::format("Lock file does not exist in directory '{}'", m_DataDir));
}
CbValidateError ValidateResult = CbValidateError::None;
if (CbObject LockFileObject =
@@ -170,33 +173,29 @@ AttachCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
std::string Reason;
if (!ValidateLockFileInfo(Info, Reason))
{
- ZEN_CONSOLE_ERROR("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, Reason);
- return 1;
+ throw std::runtime_error(fmt::format("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, Reason));
}
Entry = Instance.LookupByEffectivePort(Info.EffectiveListenPort);
}
else
{
- ZEN_CONSOLE_ERROR("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, ToString(ValidateResult));
- return 1;
+ throw std::runtime_error(
+ fmt::format("Lock file in directory '{}' is malformed. Reason: '{}'", m_DataDir, ToString(ValidateResult)));
}
}
if (!Entry)
{
- ZEN_CONSOLE_ERROR("No zen server instance to add sponsor process to");
- return 1;
+ throw std::runtime_error("No zen server instance to add sponsor process to");
}
// Sponsor processes are checked every second, so 2 second wait time should be enough
if (!Entry->AddSponsorProcess(m_OwnerPid, 2000))
{
- ZEN_CONSOLE_ERROR("Unable to add sponsor process to running zen server instance");
- return 1;
+ throw std::runtime_error("Unable to add sponsor process to running zen server instance");
}
ZEN_CONSOLE("Added sponsor process {} to running instance {} on port {}", m_OwnerPid, Entry->Pid.load(), m_Port);
- return 0;
}
//////////////////////////////////////////////////////////////////////////
@@ -211,14 +210,14 @@ DownCommand::DownCommand()
DownCommand::~DownCommand() = default;
-int
+void
DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
// Discover executing instances
@@ -236,8 +235,7 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (!IsFile(m_DataDir / ".lock"))
{
- ZEN_CONSOLE_ERROR("Lock file does not exist in directory '{}'", m_DataDir);
- return 1;
+ throw std::runtime_error(fmt::format("Lock file does not exist in directory '{}'", m_DataDir));
}
CbValidateError ValidateResult = CbValidateError::None;
if (CbObject LockFileObject =
@@ -248,15 +246,14 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
std::string Reason;
if (!ValidateLockFileInfo(Info, Reason))
{
- ZEN_CONSOLE_ERROR("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, Reason);
- return 1;
+ throw std::runtime_error(fmt::format("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, Reason));
}
Entry = Instance.LookupByEffectivePort(Info.EffectiveListenPort);
}
else
{
- ZEN_CONSOLE_ERROR("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, ToString(ValidateResult));
- return 1;
+ throw std::runtime_error(
+ fmt::format("Lock file in directory '{}' is malformed. Reason: '{}'", m_DataDir, ToString(ValidateResult)));
}
}
@@ -282,7 +279,7 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (Server.WaitUntilExited(100, Ec) && !Ec)
{
ZEN_CONSOLE("shutdown complete");
- return 0;
+ return;
}
else if (Ec)
{
@@ -318,12 +315,12 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (Entry == nullptr)
{
ZEN_CONSOLE("Shutdown complete");
- return 0;
+ return;
}
if (Entry->Pid.load() != ServerProcessPid)
{
ZEN_CONSOLE("Shutdown complete");
- return 0;
+ return;
}
Sleep(100);
}
@@ -337,21 +334,12 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (std::error_code Ec = FindProcess(ServerExePath, RunningProcess); !Ec, /*IncludeSelf*/ false)
{
ZEN_CONSOLE_WARN("Attempting hard terminate of zen process with pid ({})", RunningProcess.Pid());
- try
- {
- if (RunningProcess.Terminate(0))
- {
- ZEN_CONSOLE("Terminate complete");
- return 0;
- }
- ZEN_CONSOLE_ERROR("Failed to terminate server, still running");
- return 1;
- }
- catch (const std::exception& Ex)
+ if (RunningProcess.Terminate(0))
{
- ZEN_CONSOLE_ERROR("Failed to terminate server: '{}'", Ex.what());
- return 1;
+ ZEN_CONSOLE("Terminate complete");
+ return;
}
+ throw std::runtime_error("Failed to terminate server, still running");
}
else
{
@@ -360,13 +348,11 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
else if (Entry)
{
- ZEN_CONSOLE_ERROR("Failed to shutdown of server on port {}, use --force to hard terminate process",
- Entry->DesiredListenPort.load());
- return 1;
+ throw std::runtime_error(
+ fmt::format("Failed to shutdown of server on port {}, use --force to hard terminate process", Entry->DesiredListenPort.load()));
}
ZEN_CONSOLE("No zen server to bring down");
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/up_cmd.h b/src/zen/cmds/up_cmd.h
index c9af16749..2e822d5fc 100644
--- a/src/zen/cmds/up_cmd.h
+++ b/src/zen/cmds/up_cmd.h
@@ -14,7 +14,7 @@ public:
UpCommand();
~UpCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -31,7 +31,7 @@ public:
AttachCommand();
~AttachCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -47,7 +47,7 @@ public:
DownCommand();
~DownCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/version_cmd.cpp b/src/zen/cmds/version_cmd.cpp
index 1be02331d..979278e6c 100644
--- a/src/zen/cmds/version_cmd.cpp
+++ b/src/zen/cmds/version_cmd.cpp
@@ -32,13 +32,13 @@ VersionCommand::VersionCommand()
VersionCommand::~VersionCommand() = default;
-int
+void
VersionCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
std::string Version;
@@ -69,13 +69,14 @@ VersionCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
Parameters.Entries.insert_or_assign("detailed", "true");
}
const std::string_view VersionRequest("/health/version"sv);
- HttpClient::Response Response = Client.Get(VersionRequest, {}, Parameters);
- if (!Response.IsSuccess())
+ if (HttpClient::Response Response = Client.Get(VersionRequest, {}, Parameters))
{
- ZEN_CONSOLE_ERROR("{} failed: {}", VersionRequest, Response.ErrorMessage(""sv));
- return 1;
+ Version = Response.AsText();
+ }
+ else
+ {
+ Response.ThrowError(fmt::format("{} failed", VersionRequest));
}
- Version = Response.AsText();
}
if (m_OutputPath.empty())
@@ -90,7 +91,6 @@ VersionCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
OutputFile.Write(Version.data(), Version.length(), 0);
OutputFile.Close();
}
-
- return 0;
}
+
} // namespace zen
diff --git a/src/zen/cmds/version_cmd.h b/src/zen/cmds/version_cmd.h
index 7a910e463..934ede868 100644
--- a/src/zen/cmds/version_cmd.h
+++ b/src/zen/cmds/version_cmd.h
@@ -15,7 +15,7 @@ public:
VersionCommand();
~VersionCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/vfs_cmd.cpp b/src/zen/cmds/vfs_cmd.cpp
index e8802d990..79ec20ce2 100644
--- a/src/zen/cmds/vfs_cmd.cpp
+++ b/src/zen/cmds/vfs_cmd.cpp
@@ -28,14 +28,14 @@ VfsCommand::~VfsCommand()
{
}
-int
+void
VfsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions, argc, argv);
- if (!ZenCmdBase::ParseOptions(argc, argv))
+ if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
// Validate arguments
@@ -43,14 +43,14 @@ VfsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
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_Verb == "mount"sv)
{
if (m_MountPath.empty())
- throw OptionParseException("No source specified");
+ throw OptionParseException("'--vfs-path' is required", m_Options.help());
CbObjectWriter Cbo;
Cbo << "method"
@@ -66,8 +66,6 @@ VfsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
else
{
Result.ThrowError("VFS mount request failed"sv);
-
- return 1;
}
}
else if (m_Verb == "unmount"sv)
@@ -82,8 +80,6 @@ VfsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
else
{
Result.ThrowError("VFS unmount request failed"sv);
-
- return 1;
}
}
else if (m_Verb == "info"sv)
@@ -97,12 +93,8 @@ VfsCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
else
{
Result.ThrowError("VFS info fetch failed"sv);
-
- return 1;
}
}
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/vfs_cmd.h b/src/zen/cmds/vfs_cmd.h
index 9b2497c0e..5deaa02fa 100644
--- a/src/zen/cmds/vfs_cmd.h
+++ b/src/zen/cmds/vfs_cmd.h
@@ -12,7 +12,7 @@ public:
VfsCommand();
~VfsCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/cmds/wipe_cmd.cpp b/src/zen/cmds/wipe_cmd.cpp
index 5a9d0174e..d2bc2f5c4 100644
--- a/src/zen/cmds/wipe_cmd.cpp
+++ b/src/zen/cmds/wipe_cmd.cpp
@@ -543,7 +543,7 @@ WipeCommand::WipeCommand()
WipeCommand::~WipeCommand() = default;
-int
+void
WipeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
@@ -553,9 +553,9 @@ WipeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
signal(SIGBREAK, SignalCallbackHandler);
#endif // ZEN_PLATFORM_WINDOWS
- if (!ZenCmdBase::ParseOptions(argc, argv))
+ if (!ParseOptions(argc, argv))
{
- return 0;
+ return;
}
Quiet = m_Quiet;
@@ -567,7 +567,7 @@ WipeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (!IsDir(m_Directory))
{
- return 0;
+ return;
}
while (!m_Yes)
@@ -583,13 +583,11 @@ WipeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
else if (Reponse == "n" || Reponse == "no")
{
- return 0;
+ return;
}
}
CleanDirectory(m_Directory, {}, !m_KeepReadOnlyFiles, m_Dryrun);
-
- return 0;
}
} // namespace zen
diff --git a/src/zen/cmds/wipe_cmd.h b/src/zen/cmds/wipe_cmd.h
index 0e910bb81..d0693a757 100644
--- a/src/zen/cmds/wipe_cmd.h
+++ b/src/zen/cmds/wipe_cmd.h
@@ -18,7 +18,7 @@ public:
~WipeCommand();
virtual cxxopts::Options& Options() override { return m_Options; }
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual ZenCmdCategory& CommandCategory() const override { return g_UtilitiesCategory; }
private:
diff --git a/src/zen/cmds/workspaces_cmd.cpp b/src/zen/cmds/workspaces_cmd.cpp
index 3930e56b7..9bb118eac 100644
--- a/src/zen/cmds/workspaces_cmd.cpp
+++ b/src/zen/cmds/workspaces_cmd.cpp
@@ -117,7 +117,7 @@ WorkspaceCommand::WorkspaceCommand()
WorkspaceCommand::~WorkspaceCommand() = default;
-int
+void
WorkspaceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
@@ -129,12 +129,12 @@ WorkspaceCommand::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());
}
m_HostName = ResolveTargetHostSpec(m_HostName);
@@ -144,7 +144,7 @@ WorkspaceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
m_SystemRootDir = PickDefaultSystemRootDirectory();
if (m_SystemRootDir.empty())
{
- throw zen::OptionParseException("unable to resolve system root directory");
+ throw std::runtime_error("Unable to resolve default system root directory");
}
}
@@ -152,14 +152,14 @@ WorkspaceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (!ParseOptions(*SubOption, gsl::narrow<int>(SubCommandArguments.size()), SubCommandArguments.data()))
{
- return 0;
+ return;
}
if (SubOption == &m_CreateOptions)
{
if (m_Path.empty())
{
- throw zen::OptionParseException(fmt::format("path is required\n{}", m_CreateOptions.help()));
+ throw OptionParseException("'--root-path' is required", SubOption->help());
}
std::filesystem::path Path = StringToPath(m_Path);
@@ -167,12 +167,12 @@ WorkspaceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (m_Id.empty())
{
m_Id = Workspaces::PathToId(Path).ToString();
- ZEN_CONSOLE("Using generated workspace id {} from path '{}'", m_Id, Path);
+ ZEN_CONSOLE("Using generated workspace id '{}' from '--root-path' '{}'", m_Id, Path);
}
if (Oid::TryFromHexString(m_Id) == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("id '{}' is invalid", m_Id));
+ throw OptionParseException(fmt::format("'--workspace' ('{}') is malformed", m_Id), SubOption->help());
}
if (Workspaces::AddWorkspace(
@@ -185,16 +185,16 @@ WorkspaceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
HttpClient Http(m_HostName);
if (HttpClient::Response Result = Http.Get("/ws/refresh"); !Result)
{
- ZEN_CONSOLE_ERROR("Failed to refresh workspaces for host {}. Reason: '{}'", m_HostName, Result.ErrorMessage(""sv));
+ ZEN_CONSOLE_WARN("Failed to refresh workspaces for host {}. Reason: '{}'", m_HostName, Result.ErrorMessage(""sv));
}
}
ZEN_CONSOLE("Added/updated workspace {}", m_Id);
- return 0;
+ return;
}
else
{
ZEN_CONSOLE_WARN("Workspace {} already exists", m_Id);
- return 0;
+ return;
}
}
@@ -206,7 +206,7 @@ WorkspaceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
static std::vector<Workspaces::WorkspaceConfiguration> Configs = Workspaces::ReadConfig(Log(), StatePath, Error);
if (!Error.empty())
{
- ZEN_CONSOLE_ERROR("Failed to read workspaces state from '{}'. Reason: '{}'", StatePath, Error);
+ throw std::runtime_error(fmt::format("Failed to read workspaces state from '{}'. Reason: '{}'", StatePath, Error));
}
else
{
@@ -216,20 +216,20 @@ WorkspaceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
ShowWorkspace(Config, " "sv);
}
}
- return 0;
+ return;
}
else
{
if (Oid::TryFromHexString(m_Id) == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("id '{}' is invalid", m_Id));
+ throw OptionParseException(fmt::format("'--workspace' ('{}') is malformed", m_Id), SubOption->help());
}
Workspaces::WorkspaceConfiguration Workspace = Workspaces::FindWorkspace(Log(), StatePath, Oid::FromHexString(m_Id));
if (Workspace.Id != Oid::Zero)
{
ShowWorkspace(Workspace, ""sv);
- return 0;
+ return;
}
else
{
@@ -242,12 +242,12 @@ WorkspaceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
if (m_Id.empty())
{
- throw zen::OptionParseException(fmt::format("id is required", m_RemoveOptions.help()));
+ throw OptionParseException("'--workspace' is required", SubOption->help());
}
if (Oid::TryFromHexString(m_Id) == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("id '{}' is invalid", m_Id));
+ throw OptionParseException(fmt::format("'--workspace' ('{}') is malformed", m_Id), SubOption->help());
}
if (Workspaces::RemoveWorkspace(Log(), StatePath, Oid::FromHexString(m_Id)))
@@ -257,7 +257,7 @@ WorkspaceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
HttpClient Http(m_HostName);
if (HttpClient::Response Result = Http.Get("/ws/refresh"); !Result)
{
- ZEN_CONSOLE_ERROR("Failed to refresh workspaces for host {}. Reason: '{}'", m_HostName, Result.ErrorMessage(""sv));
+ ZEN_CONSOLE_WARN("Failed to refresh workspaces for host {}. Reason: '{}'", m_HostName, Result.ErrorMessage(""sv));
}
}
ZEN_CONSOLE("Removed workspace {}", m_Id);
@@ -266,7 +266,7 @@ WorkspaceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_CONSOLE_WARN("Workspace {} does not exist", m_Id);
}
- return 0;
+ return;
}
ZEN_ASSERT(false);
@@ -368,7 +368,7 @@ WorkspaceShareCommand::WorkspaceShareCommand()
WorkspaceShareCommand::~WorkspaceShareCommand() = default;
-int
+void
WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
ZEN_UNUSED(GlobalOptions);
@@ -380,12 +380,12 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
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());
}
m_HostName = ResolveTargetHostSpec(m_HostName);
@@ -395,7 +395,7 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
m_SystemRootDir = PickDefaultSystemRootDirectory();
if (m_SystemRootDir.empty())
{
- throw zen::OptionParseException("unable to resolve system root directory");
+ throw std::runtime_error("Unable to resolve default system root directory");
}
}
else
@@ -407,7 +407,7 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
if (!ParseOptions(*SubOption, gsl::narrow<int>(SubCommandArguments.size()), SubCommandArguments.data()))
{
- return 0;
+ return;
}
if (SubOption == &m_CreateOptions)
@@ -416,20 +416,19 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
{
if (m_WorkspaceId.empty())
{
- throw zen::OptionParseException("workspace id or root path is required");
+ throw OptionParseException("'--workspace' or '--root-path' is required", SubOption->help());
}
Oid WorkspaceId = Oid::TryFromHexString(m_WorkspaceId);
if (WorkspaceId == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("id '{}' is invalid", m_WorkspaceId));
+ throw OptionParseException(fmt::format("'--workspace' ('{}') is malformed", m_WorkspaceId), SubOption->help());
}
Workspaces::WorkspaceConfiguration WorkspaceConfig = Workspaces::FindWorkspace(Log(), StatePath, WorkspaceId);
if (WorkspaceConfig.Id == Oid::Zero)
{
- ZEN_CONSOLE_ERROR("Workspace {} does not exist", m_WorkspaceId);
- return 0;
+ throw std::runtime_error(fmt::format("Workspace {} does not exist", m_WorkspaceId));
}
m_WorkspaceRoot = WorkspaceConfig.RootPath;
}
@@ -445,7 +444,7 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
{
if (Oid::TryFromHexString(m_WorkspaceId) == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("workspace id '{}' is invalid", m_WorkspaceId));
+ throw OptionParseException(fmt::format("'--workspace' ('{}') is malformed", m_WorkspaceId), SubOption->help());
}
}
if (Workspaces::AddWorkspace(Log(), StatePath, {.Id = Oid::FromHexString(m_WorkspaceId), .RootPath = m_WorkspaceRoot}))
@@ -469,7 +468,7 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
if (Oid::TryFromHexString(m_ShareId) == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("workspace id '{}' is invalid", m_ShareId));
+ throw OptionParseException(fmt::format("'--workspace' ('{}') is malformed", m_ShareId), SubOption->help());
}
if (Workspaces::AddWorkspaceShare(Log(),
@@ -481,16 +480,14 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
HttpClient Http(m_HostName);
if (HttpClient::Response Result = Http.Get("/ws/refresh"); !Result)
{
- ZEN_CONSOLE_ERROR("Failed to refresh workspaces for host {}. Reason: '{}'", m_HostName, Result.ErrorMessage(""sv));
+ ZEN_CONSOLE_WARN("Failed to refresh workspaces for host {}. Reason: '{}'", m_HostName, Result.ErrorMessage(""sv));
}
}
ZEN_CONSOLE("Created workspace share {}", m_ShareId);
- return 0;
}
else
{
ZEN_CONSOLE("Workspace share {} already exists", m_ShareId);
- return 0;
}
}
@@ -503,50 +500,47 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
Workspaces::FindWorkspaceShare(Log(), StatePath, m_Alias, WorkspaceConfig);
if (ShareConfig.Id == Oid::Zero)
{
- ZEN_CONSOLE("Workspace share with alias {} does not exist", m_Alias);
- return 0;
+ throw std::runtime_error(fmt::format("Workspace share with alias {} does not exist", m_Alias));
}
ShowShare(ShareConfig, WorkspaceConfig.Id, ""sv);
- return 0;
+ return;
}
if (m_WorkspaceId.empty())
{
- throw zen::OptionParseException("workspace id or root path is required");
+ throw OptionParseException("'--workspace' or '--root-path' is required", SubOption->help());
}
if (Oid::TryFromHexString(m_WorkspaceId) == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("workspace id '{}' is invalid", m_WorkspaceId));
+ throw OptionParseException(fmt::format("'--workspace' ('{}') is malformed", m_WorkspaceId), SubOption->help());
}
Workspaces::WorkspaceConfiguration WorkspaceConfig = Workspaces::FindWorkspace(Log(), StatePath, Oid::FromHexString(m_WorkspaceId));
if (WorkspaceConfig.Id == Oid::Zero)
{
- ZEN_CONSOLE("Workspace {} does not exist", m_WorkspaceId);
- return 0;
+ throw std::runtime_error(fmt::format("Workspace {} does not exist", m_WorkspaceId));
}
std::filesystem::path WorkspaceRoot = WorkspaceConfig.RootPath;
if (m_ShareId.empty())
{
- throw zen::OptionParseException("share id is required");
+ throw OptionParseException("'--share' is required", SubOption->help());
}
if (Oid::TryFromHexString(m_ShareId) == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("workspace id '{}' is invalid", m_ShareId));
+ throw OptionParseException(fmt::format("'--share' ('{}') is malformed", m_ShareId), SubOption->help());
}
Workspaces::WorkspaceShareConfiguration Share = Workspaces::FindWorkspaceShare(Log(), WorkspaceRoot, Oid::FromHexString(m_ShareId));
if (Share.Id == Oid::Zero)
{
- ZEN_CONSOLE("Workspace share {} does not exist", m_ShareId);
- return 0;
+ throw std::runtime_error(fmt::format("Workspace share {} does not exist", m_ShareId));
}
ShowShare(Share, Oid::Zero, ""sv);
- return 0;
+ return;
}
if (SubOption == &m_RemoveOptions)
@@ -560,7 +554,7 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
if (ShareConfig.Id == Oid::Zero)
{
ZEN_CONSOLE("Workspace share with alias {} does not exist", m_Alias);
- return 0;
+ return;
}
m_ShareId = ShareConfig.Id.ToString();
m_WorkspaceId = WorkspaceConfig.Id.ToString();
@@ -569,30 +563,30 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
if (m_WorkspaceId.empty())
{
- throw zen::OptionParseException("workspace id or root path is required");
+ throw OptionParseException("'--workspace' or '--root-path' is required", SubOption->help());
}
if (Oid::TryFromHexString(m_WorkspaceId) == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("workspace id '{}' is invalid", m_WorkspaceId));
+ throw OptionParseException(fmt::format("'--workspace' ('{}') is malformed", m_WorkspaceId), SubOption->help());
}
Workspaces::WorkspaceConfiguration WorkspaceConfig = Workspaces::FindWorkspace(Log(), StatePath, Oid::FromHexString(m_WorkspaceId));
if (WorkspaceConfig.Id == Oid::Zero)
{
ZEN_CONSOLE("Workspace {} does not exist", m_WorkspaceId);
- return 0;
+ return;
}
WorkspaceRoot = WorkspaceConfig.RootPath;
if (m_ShareId.empty())
{
- throw zen::OptionParseException("share id is required");
+ throw OptionParseException("'--share' is required", SubOption->help());
}
if (Oid::TryFromHexString(m_ShareId) == Oid::Zero)
{
- throw zen::OptionParseException(fmt::format("workspace id '{}' is invalid", m_ShareId));
+ throw OptionParseException(fmt::format("'--share' ('{}') is malformed", m_ShareId), SubOption->help());
}
if (Workspaces::RemoveWorkspaceShare(Log(), WorkspaceRoot, Oid::FromHexString(m_ShareId)))
@@ -602,16 +596,16 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
HttpClient Http(m_HostName);
if (HttpClient::Response Result = Http.Get("/ws/refresh"); !Result)
{
- ZEN_CONSOLE_ERROR("Failed to refresh workspaces for host {}. Reason: '{}'", m_HostName, Result.ErrorMessage(""sv));
+ ZEN_CONSOLE_WARN("Failed to refresh workspaces for host {}. Reason: '{}'", m_HostName, Result.ErrorMessage(""sv));
}
}
ZEN_CONSOLE("Removed workspace share {}", m_ShareId);
- return 0;
+ return;
}
else
{
ZEN_CONSOLE("Removed workspace share {} does not exist", m_ShareId);
- return 0;
+ return;
}
}
@@ -620,12 +614,12 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
{
if (m_WorkspaceId.empty())
{
- throw zen::OptionParseException("workspace id is required");
+ throw OptionParseException("'--workspace' is required", Opts.help());
}
if (m_ShareId.empty())
{
- throw zen::OptionParseException(fmt::format("share id is required", Opts.help()));
+ throw OptionParseException("'--share' is required", Opts.help());
}
return fmt::format("{}/{}", m_WorkspaceId, m_ShareId);
}
@@ -649,20 +643,19 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
if (m_HostName.empty())
{
- throw zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", SubOption->help());
}
HttpClient Http(m_HostName);
if (HttpClient::Response Result = Http.Get(fmt::format("/ws/{}/files", GetShareIdentityUrl(m_FilesOptions)), {}, Params))
{
ZEN_CONSOLE("{}: {}", Result, Result.ToText());
- return 0;
}
else
{
Result.ThrowError("failed to get workspace share files"sv);
- return 1;
}
+ return;
}
if (SubOption == &m_EntriesOptions)
@@ -683,20 +676,19 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
if (m_HostName.empty())
{
- throw zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("Unable to resolve server specification", SubOption->help());
}
HttpClient Http(m_HostName);
if (HttpClient::Response Result = Http.Get(fmt::format("/ws/{}/entries", GetShareIdentityUrl(m_EntriesOptions)), {}, Params))
{
ZEN_CONSOLE("{}: {}", Result, Result.ToText());
- return 0;
}
else
{
Result.ThrowError("failed to get workspace share entries"sv);
- return 1;
}
+ return;
}
auto ChunksToOidStrings = [](HttpClient& Http,
@@ -751,14 +743,14 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
if (SubOption == &m_GetChunkOptions)
{
- if (m_ChunkId.empty())
+ if (m_HostName.empty())
{
- throw zen::OptionParseException("chunk id is required");
+ throw OptionParseException("Unable to resolve server specification", SubOption->help());
}
- if (m_HostName.empty())
+ if (m_ChunkId.empty())
{
- throw zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("'--chunk' is required", SubOption->help());
}
HttpClient Http(m_HostName);
@@ -777,30 +769,29 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
if (HttpClient::Response Result = Http.Get(fmt::format("/ws/{}/{}", GetShareIdentityUrl(m_GetChunkOptions), m_ChunkId), {}, Params))
{
ZEN_CONSOLE("{}: Bytes: {}", Result, NiceBytes(Result.ResponsePayload.GetSize()));
- return 0;
}
else
{
Result.ThrowError("failed to get workspace share chunk"sv);
- return 1;
}
+ return;
}
if (SubOption == &m_GetChunkBatchOptions)
{
- if (m_ShareId.empty())
+ if (m_HostName.empty())
{
- throw zen::OptionParseException(fmt::format("share id is required", m_InfoOptions.help()));
+ throw OptionParseException("Unable to resolve server specification", SubOption->help());
}
- if (m_ChunkIds.empty())
+ if (m_ShareId.empty())
{
- throw zen::OptionParseException("share is is required");
+ throw OptionParseException("'--share' is required", SubOption->help());
}
- if (m_HostName.empty())
+ if (m_ChunkIds.empty())
{
- throw zen::OptionParseException("unable to resolve server specification");
+ throw OptionParseException("'--chunks' is required", SubOption->help());
}
HttpClient Http(m_HostName);
@@ -832,13 +823,12 @@ WorkspaceShareCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char**
{
ZEN_CONSOLE("{}: Bytes: {}", m_ChunkIds[Index], NiceBytes(Results[Index].GetSize()));
}
- return 0;
}
else
{
Result.ThrowError("failed to get workspace share batch"sv);
- return 1;
}
+ return;
}
ZEN_ASSERT(false);
diff --git a/src/zen/cmds/workspaces_cmd.h b/src/zen/cmds/workspaces_cmd.h
index d85d8f7d8..f5880125b 100644
--- a/src/zen/cmds/workspaces_cmd.h
+++ b/src/zen/cmds/workspaces_cmd.h
@@ -17,7 +17,7 @@ public:
WorkspaceCommand();
~WorkspaceCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
@@ -49,7 +49,7 @@ public:
WorkspaceShareCommand();
~WorkspaceShareCommand();
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override;
virtual cxxopts::Options& Options() override { return m_Options; }
private:
diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp
index 240ba2a81..db63624ce 100644
--- a/src/zen/zen.cpp
+++ b/src/zen/zen.cpp
@@ -72,6 +72,35 @@ ZEN_THIRD_PARTY_INCLUDES_END
namespace zen {
+enum class ReturnCode : std::int8_t
+{
+ kSuccess = 0,
+
+ kOtherError = 1,
+
+ kBadInput = 2,
+ kOutOfMemory = 16,
+ kOutOfDisk = 17,
+ kAssertError = 70,
+
+ kHttpOtherClientError = 80,
+ kHttpCantConnectError = 81, // CONNECTION_FAILURE
+ kHttpNotFound = 66, // NotFound(404)
+ kHttpUnauthorized = 77, // Unauthorized(401),
+ kHttpSLLError =
+ 82, // SSL_CONNECT_ERROR, SSL_LOCAL_CERTIFICATE_ERROR, SSL_REMOTE_CERTIFICATE_ERROR, SSL_CACERT_ERROR, GENERIC_SSL_ERROR
+ kHttpForbidden = 83, // Forbidden(403)
+ kHttpTimeout = 84, // NETWORK_RECEIVE_ERROR, NETWORK_SEND_FAILURE, OPERATION_TIMEDOUT, RequestTimeout(408)
+ kHttpConflict = 85, // Conflict(409)
+ kHttpNoHost = 86, // HOST_RESOLUTION_FAILURE, PROXY_RESOLUTION_FAILURE
+
+ kHttpOtherServerError = 90,
+ kHttpInternalServerError = 91, // InternalServerError(500)
+ kHttpServiceUnavailable = 69, // ServiceUnavailable(503)
+ kHttpBadGateway = 92, // BadGateway(502)
+ kHttpGatewayTimeout = 93, // GatewayTimeout(504)
+};
+
ZenCmdCategory DefaultCategory{.Name = "general commands"};
ZenCmdCategory g_UtilitiesCategory{.Name = "utility commands"};
ZenCmdCategory g_ProjectStoreCategory{.Name = "project store commands"};
@@ -101,7 +130,7 @@ ZenCmdBase::ParseOptions(cxxopts::Options& CmdOptions, int argc, char** argv)
}
catch (const std::exception& Ex)
{
- throw zen::OptionParseException(Ex.what());
+ throw zen::OptionParseException(Ex.what(), CmdOptions.help());
}
CmdOptions.show_positional_help();
@@ -127,7 +156,7 @@ ZenCmdBase::ParseOptions(cxxopts::Options& CmdOptions, int argc, char** argv)
First = false;
}
- throw zen::OptionParseException(fmt::format("Invalid arguments: {}", StringBuilder.ToView()));
+ throw zen::OptionParseException(fmt::format("Invalid arguments: {}", StringBuilder.ToView()), {});
}
return true;
@@ -161,62 +190,68 @@ ZenCmdBase::GetSubCommand(cxxopts::Options&,
return argc;
}
-std::string
-ZenCmdBase::FormatHttpResponse(const cpr::Response& Response)
+static ReturnCode
+GetReturnCodeFromHttpResult(int Error, HttpResponseCode ResponseCode)
{
- if (Response.error.code != cpr::ErrorCode::OK)
+ if ((cpr::ErrorCode)Error != cpr::ErrorCode::OK)
{
- if (Response.error.message.empty())
+ switch ((cpr::ErrorCode)Error)
{
- return fmt::format("Request '{}' failed, error code {}", Response.url.str(), static_cast<int>(Response.error.code));
+ case cpr::ErrorCode::CONNECTION_FAILURE:
+ return ReturnCode::kHttpCantConnectError;
+ case cpr::ErrorCode::HOST_RESOLUTION_FAILURE:
+ case cpr::ErrorCode::PROXY_RESOLUTION_FAILURE:
+ return ReturnCode::kHttpNoHost;
+ case cpr::ErrorCode::INTERNAL_ERROR:
+ case cpr::ErrorCode::NETWORK_RECEIVE_ERROR:
+ case cpr::ErrorCode::NETWORK_SEND_FAILURE:
+ case cpr::ErrorCode::OPERATION_TIMEDOUT:
+ return ReturnCode::kHttpTimeout;
+ case cpr::ErrorCode::SSL_CONNECT_ERROR:
+ case cpr::ErrorCode::SSL_LOCAL_CERTIFICATE_ERROR:
+ case cpr::ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR:
+ case cpr::ErrorCode::SSL_CACERT_ERROR:
+ case cpr::ErrorCode::GENERIC_SSL_ERROR:
+ return ReturnCode::kHttpSLLError;
+ default:
+ return ReturnCode::kHttpOtherClientError;
}
- return fmt::format("Request '{}' failed. Reason: '{}' ({})",
- Response.url.str(),
- Response.error.message,
- static_cast<int>(Response.error.code));
}
-
- std::string Content;
- if (auto It = Response.header.find("Content-Type"); It != Response.header.end())
- {
- zen::HttpContentType ContentType = zen::ParseContentType(It->second);
- if (ContentType == zen::HttpContentType::kText)
- {
- Content = Response.text;
- }
- else if (ContentType == zen::HttpContentType::kJSON)
- {
- Content = fmt::format("\n{}", Response.text);
- }
- else if (!Response.text.empty())
- {
- Content = fmt::format("[{}]", MapContentTypeToString(ContentType));
- }
- }
-
- std::string_view ResponseString = zen::ReasonStringForHttpResultCode(
- Response.status_code == static_cast<long>(zen::HttpResponseCode::NoContent) ? static_cast<long>(zen::HttpResponseCode::OK)
- : Response.status_code);
- if (Content.empty())
- {
- return std::string(ResponseString);
- }
-
- return fmt::format("{}: {}", ResponseString, Content);
-}
-
-int
-ZenCmdBase::MapHttpToCommandReturnCode(const cpr::Response& Response)
-{
- if (zen::IsHttpSuccessCode(Response.status_code))
+ else if (IsHttpSuccessCode(ResponseCode))
{
- return 0;
+ return ReturnCode::kSuccess;
}
- if (Response.error.code != cpr::ErrorCode::OK)
+ else
{
- return static_cast<int>(Response.error.code);
+ switch (ResponseCode)
+ {
+ case HttpResponseCode::Unauthorized:
+ return ReturnCode::kHttpUnauthorized;
+ case HttpResponseCode::NotFound:
+ return ReturnCode::kHttpNotFound;
+ case HttpResponseCode::Forbidden:
+ return ReturnCode::kHttpForbidden;
+ case HttpResponseCode::Conflict:
+ return ReturnCode::kHttpConflict;
+ case HttpResponseCode::InternalServerError:
+ return ReturnCode::kHttpInternalServerError;
+ case HttpResponseCode::ServiceUnavailable:
+ return ReturnCode::kHttpServiceUnavailable;
+ case HttpResponseCode::BadGateway:
+ return ReturnCode::kHttpBadGateway;
+ case HttpResponseCode::GatewayTimeout:
+ return ReturnCode::kHttpGatewayTimeout;
+ default:
+ if (ResponseCode >= HttpResponseCode::InternalServerError)
+ {
+ return ReturnCode::kHttpOtherServerError;
+ }
+ else
+ {
+ return ReturnCode::kHttpOtherClientError;
+ }
+ }
}
- return 1;
}
std::string
@@ -945,7 +980,7 @@ main(int argc, char** argv)
printf("\n");
}
- exit(0);
+ return (int)ReturnCode::kSuccess;
}
#if ZEN_USE_SENTRY
@@ -1022,86 +1057,107 @@ main(int argc, char** argv)
{
if (StrCaseCompare(SubCommand.c_str(), CmdInfo.CmdName) == 0)
{
- cxxopts::Options& VerbOptions = CmdInfo.Cmd->Options();
-
try
{
- return CmdInfo.Cmd->Run(GlobalOptions, (int)CommandArgVec.size(), CommandArgVec.data());
+ CmdInfo.Cmd->Run(GlobalOptions, (int)CommandArgVec.size(), CommandArgVec.data());
+ return (int)ReturnCode::kSuccess;
}
catch (const OptionParseException& Ex)
{
- ZEN_CONSOLE_ERROR("Invalid arguments for command '{}': {}\n\n{}", SubCommand, Ex.what(), VerbOptions.help());
- exit(11);
+ ZEN_CONSOLE("{}\n", Ex.m_Help);
+ ZEN_CONSOLE_ERROR("Invalid arguments for command '{}': {}", SubCommand, Ex.what());
+ return (int)ReturnCode::kBadInput;
}
catch (const std::system_error& Ex)
{
if (IsOOD(Ex))
{
ZEN_CONSOLE_ERROR("Operation failed due to out of disk space: {}", Ex.what());
- exit(3);
+ return (int)ReturnCode::kOutOfDisk;
}
else if (IsOOM(Ex))
{
ZEN_CONSOLE_ERROR("Operation failed due to out of memory: {}", Ex.what());
- exit(3);
+ return (int)ReturnCode::kOutOfMemory;
}
else
{
ZEN_CONSOLE_ERROR("Operation failed due to system error: {} ({})\n", Ex.what(), Ex.code() ? Ex.code().value() : 0);
- exit(Ex.code() ? Ex.code().value() : 10);
+ return (int)ReturnCode::kOtherError;
}
}
catch (const HttpClientError& Ex)
{
ZEN_CONSOLE_ERROR("Operation failed due to a http error: {}", Ex.what());
- exit(Ex.m_Error != 0 ? Ex.m_Error : (int)Ex.m_ResponseCode);
+ ReturnCode Result = GetReturnCodeFromHttpResult(Ex.m_Error, Ex.m_ResponseCode);
+ return (int)Result;
+ }
+ catch (const AssertException& Ex)
+ {
+ ZEN_CONSOLE_ERROR("Operation failed due to an assert exception: {}", Ex.FullDescription());
+ return (int)ReturnCode::kAssertError;
+ }
+ catch (const ErrorWithReturnCode& Ex)
+ {
+ ZEN_CONSOLE_ERROR("{}", Ex.what());
+ return Ex.m_ReturnCode;
}
catch (const std::exception& Ex)
{
- ZEN_CONSOLE_ERROR("Operation failed due to: {}\n", Ex.what());
- exit(11);
+ ZEN_CONSOLE_ERROR("{}\n", Ex.what());
+ return (int)ReturnCode::kOtherError;
}
}
}
printf("Unknown command specified: '%s', exiting\n", SubCommand.c_str());
+ return (int)ReturnCode::kBadInput;
}
catch (const OptionParseException& Ex)
{
- std::string HelpMessage = Options.help();
-
- printf("Error parsing program arguments: %s\n\n%s", Ex.what(), HelpMessage.c_str());
-
- return 9;
+ printf("%s\n\n", Ex.m_Help.c_str());
+ printf("Invalid arguments arguments: %s", Ex.what());
+ return (int)ReturnCode::kBadInput;
}
catch (const std::system_error& Ex)
{
if (IsOOD(Ex))
{
printf("Operation failed due to out of disk space: %s", Ex.what());
- return 3;
+ return (int)ReturnCode::kOutOfDisk;
}
else if (IsOOM(Ex))
{
printf("Operation failed due to out of memory: %s", Ex.what());
- return 3;
+ return (int)ReturnCode::kOutOfMemory;
}
else
{
printf("Operation failed due to system error: %s (%d)\n", Ex.what(), Ex.code() ? Ex.code().value() : 0);
- return Ex.code() ? Ex.code().value() : 10;
+ return (int)ReturnCode::kOtherError;
}
}
catch (const HttpClientError& Ex)
{
- printf("Operation failed due to a http error: %s", Ex.what());
- return Ex.m_Error != 0 ? Ex.m_Error : (int)Ex.m_ResponseCode;
+ printf("Error: Operation failed due to a http error: %s", Ex.what());
+ ReturnCode Result = GetReturnCodeFromHttpResult(Ex.m_Error, Ex.m_ResponseCode);
+ return (int)Result;
+ }
+ catch (const AssertException& Ex)
+ {
+ printf("Error: Operation failed due to an assert exception: %s", Ex.FullDescription().c_str());
+ return (int)ReturnCode::kAssertError;
+ }
+ catch (const ErrorWithReturnCode& Ex)
+ {
+ printf("Error: %s", Ex.what());
+ return Ex.m_ReturnCode;
}
catch (const std::exception& Ex)
{
- printf("Operation failed due to: %s\n", Ex.what());
- return 11;
+ printf("Error: %s\n", Ex.what());
+ return (int)ReturnCode::kOtherError;
}
- return 0;
+ return (int)ReturnCode::kSuccess;
}
diff --git a/src/zen/zen.h b/src/zen/zen.h
index 40c745bc7..5ff7066a0 100644
--- a/src/zen/zen.h
+++ b/src/zen/zen.h
@@ -7,10 +7,6 @@
#include <zencore/zencore.h>
#include <zenutil/commandlineoptions.h>
-namespace cpr {
-class Response;
-}
-
namespace zen {
struct ZenCliOptions
@@ -35,13 +31,24 @@ extern ZenCmdCategory g_ProjectStoreCategory;
extern ZenCmdCategory g_CacheStoreCategory;
extern ZenCmdCategory g_StorageCategory;
+class ErrorWithReturnCode : public std::runtime_error
+{
+public:
+ using _Mybase = runtime_error;
+ ErrorWithReturnCode(const std::string& Message, int InReturnCode) : _Mybase(Message), m_ReturnCode(InReturnCode) {}
+
+ ErrorWithReturnCode(const char* Message, int InReturnCode) : _Mybase(Message), m_ReturnCode(InReturnCode) {}
+
+ const int m_ReturnCode = -1;
+};
+
/** Base class for command implementations
*/
class ZenCmdBase
{
public:
- virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) = 0;
+ virtual void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) = 0;
virtual cxxopts::Options& Options() = 0;
virtual ZenCmdCategory& CommandCategory() const;
@@ -53,8 +60,6 @@ public:
std::span<cxxopts::Options*> SubOptions,
cxxopts::Options*& OutSubOption,
std::vector<char*>& OutSubCommandArguments);
- static std::string FormatHttpResponse(const cpr::Response& Response);
- static int MapHttpToCommandReturnCode(const cpr::Response& Response);
static std::string ResolveTargetHostSpec(const std::string& InHostSpec);
static std::string ResolveTargetHostSpec(const std::string& InHostSpec, uint16_t& OutEffectivePort);
};
diff --git a/src/zencore/include/zencore/except.h b/src/zencore/include/zencore/except.h
index 6810e6ea9..c933adfd8 100644
--- a/src/zencore/include/zencore/except.h
+++ b/src/zencore/include/zencore/except.h
@@ -63,7 +63,9 @@ MakeErrorCodeFromLastError() noexcept
class OptionParseException : public std::runtime_error
{
public:
- inline explicit OptionParseException(const std::string& Message) : std::runtime_error(Message) {}
+ // inline explicit OptionParseException(const std::string& Message) : std::runtime_error(Message) {}
+ inline OptionParseException(const std::string& Message, const std::string& Help) : std::runtime_error(Message), m_Help(Help) {}
+ const std::string m_Help;
};
bool IsOOM(const std::system_error& SystemError);
diff --git a/src/zencore/include/zencore/uid.h b/src/zencore/include/zencore/uid.h
index 64d3b6b9b..0c1079444 100644
--- a/src/zencore/include/zencore/uid.h
+++ b/src/zencore/include/zencore/uid.h
@@ -55,8 +55,8 @@ class StringBuilderBase;
struct Oid
{
- static const int StringLength = 24;
- typedef char String_t[StringLength + 1];
+ static constexpr int StringLength = 24;
+ typedef char String_t[StringLength + 1];
static void Initialize();
[[nodiscard]] static Oid NewOid();
diff --git a/src/zenserver/config.cpp b/src/zenserver/config.cpp
index 0397677b9..0cf5a9ca3 100644
--- a/src/zenserver/config.cpp
+++ b/src/zenserver/config.cpp
@@ -99,35 +99,37 @@ ValidateOptions(ZenServerOptions& ServerOptions)
{
if (ServerOptions.EncryptionKey.empty() == false)
{
- const auto Key = zen::AesKey256Bit::FromString(ServerOptions.EncryptionKey);
+ const auto Key = AesKey256Bit::FromString(ServerOptions.EncryptionKey);
if (Key.IsValid() == false)
{
- throw zen::OptionParseException("Invalid AES encryption key");
+ throw OptionParseException(fmt::format("'--encryption-aes-key' ('{}') is malformed", ServerOptions.EncryptionKey), {});
}
}
if (ServerOptions.EncryptionIV.empty() == false)
{
- const auto IV = zen::AesIV128Bit::FromString(ServerOptions.EncryptionIV);
+ const auto IV = AesIV128Bit::FromString(ServerOptions.EncryptionIV);
if (IV.IsValid() == false)
{
- throw zen::OptionParseException("Invalid AES initialization vector");
+ throw OptionParseException(fmt::format("'--encryption-aes-iv' ('{}') is malformed", ServerOptions.EncryptionIV), {});
}
}
if (ServerOptions.HttpServerConfig.ForceLoopback && ServerOptions.IsDedicated)
{
- throw zen::OptionParseException("Dedicated server can not be used with forced local server address");
+ throw OptionParseException("'--dedicated' conflicts with '--http-forceloopback'", {});
}
if (ServerOptions.GcConfig.AttachmentPassCount > ZenGcConfig::GcMaxAttachmentPassCount)
{
- throw zen::OptionParseException(
- fmt::format("GC attachment pass count can not be larger than {}", ZenGcConfig::GcMaxAttachmentPassCount));
+ throw OptionParseException(fmt::format("'--gc-attachment-passes' ('{}') is invalid, maximum is {}.",
+ ServerOptions.GcConfig.AttachmentPassCount,
+ ZenGcConfig::GcMaxAttachmentPassCount),
+ {});
}
if (ServerOptions.GcConfig.UseGCV2 == false)
{
- ZEN_WARN("--gc-v2=false is deprecated, reverting to --gc-v2=true");
+ ZEN_WARN("'--gc-v2=false' is deprecated, reverting to '--gc-v2=true'");
ServerOptions.GcConfig.UseGCV2 = true;
}
}
@@ -185,7 +187,7 @@ class CachePolicyOption : public LuaConfig::OptionValue
{
public:
CachePolicyOption(UpstreamCachePolicy& Value) : Value(Value) {}
- virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override
+ virtual void Print(std::string_view, StringBuilderBase& StringBuilder) override
{
switch (Value)
{
@@ -232,7 +234,7 @@ class ZenAuthConfigOption : public LuaConfig::OptionValue
{
public:
ZenAuthConfigOption(ZenAuthConfig& Value) : Value(Value) {}
- virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override
+ virtual void Print(std::string_view Indent, StringBuilderBase& StringBuilder) override
{
if (Value.OpenIdProviders.empty())
{
@@ -275,7 +277,7 @@ class ZenObjectStoreConfigOption : public LuaConfig::OptionValue
{
public:
ZenObjectStoreConfigOption(ZenObjectStoreConfig& Value) : Value(Value) {}
- virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override
+ virtual void Print(std::string_view Indent, StringBuilderBase& StringBuilder) override
{
if (Value.Buckets.empty())
{
@@ -318,7 +320,7 @@ class ZenStructuredCacheBucketsConfigOption : public LuaConfig::OptionValue
{
public:
ZenStructuredCacheBucketsConfigOption(std::vector<std::pair<std::string, ZenStructuredCacheBucketConfig>>& Value) : Value(Value) {}
- virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override
+ virtual void Print(std::string_view Indent, StringBuilderBase& StringBuilder) override
{
if (Value.empty())
{
@@ -359,14 +361,15 @@ public:
std::string Name = Kv.first.as<std::string>();
if (Name.empty())
{
- throw zen::OptionParseException(fmt::format("cache bucket option must have a name."));
+ throw OptionParseException("Cache bucket option must have a name.", {});
}
const uint64_t MaxBlockSize = Bucket.value().get_or("maxblocksize", BucketConfig.MaxBlockSize);
if (MaxBlockSize == 0)
{
- throw zen::OptionParseException(
- fmt::format("maxblocksize option for cache bucket '{}' is invalid. It must be non-zero.", Name));
+ throw OptionParseException(
+ fmt::format("'maxblocksize' option for cache bucket '{}' is invalid. It must be non-zero.", Name),
+ {});
}
BucketConfig.MaxBlockSize = MaxBlockSize;
@@ -375,8 +378,9 @@ public:
const uint64_t MemCacheSizeThreshold = Bucket.value().get_or("sizethreshold", BucketConfig.MemCacheSizeThreshold);
if (MemCacheSizeThreshold == 0)
{
- throw zen::OptionParseException(
- fmt::format("memlayer.sizethreshold option for cache bucket '{}' is invalid. It must be non-zero.", Name));
+ throw OptionParseException(
+ fmt::format("'memlayer.sizethreshold' option for cache bucket '{}' is invalid. It must be non-zero.", Name),
+ {});
}
BucketConfig.MemCacheSizeThreshold = Bucket.value().get_or("sizethreshold", BucketConfig.MemCacheSizeThreshold);
}
@@ -384,17 +388,20 @@ public:
const uint32_t PayloadAlignment = Bucket.value().get_or("payloadalignment", BucketConfig.PayloadAlignment);
if (PayloadAlignment == 0 || !IsPow2(PayloadAlignment))
{
- throw zen::OptionParseException(fmt::format(
- "payloadalignment option for cache bucket '{}' is invalid. It needs to be non-zero and a power of two.",
- Name));
+ throw OptionParseException(
+ fmt::format(
+ "'payloadalignment' option for cache bucket '{}' is invalid. It needs to be non-zero and a power of two.",
+ Name),
+ {});
}
BucketConfig.PayloadAlignment = PayloadAlignment;
const uint64_t LargeObjectThreshold = Bucket.value().get_or("largeobjectthreshold", BucketConfig.LargeObjectThreshold);
if (LargeObjectThreshold == 0)
{
- throw zen::OptionParseException(
- fmt::format("largeobjectthreshold option for cache bucket '{}' is invalid. It must be non-zero.", Name));
+ throw OptionParseException(
+ fmt::format("'largeobjectthreshold' option for cache bucket '{}' is invalid. It must be non-zero.", Name),
+ {});
}
BucketConfig.LargeObjectThreshold = LargeObjectThreshold;
@@ -409,19 +416,19 @@ public:
};
std::shared_ptr<LuaConfig::OptionValue>
-MakeOption(zen::UpstreamCachePolicy& Value)
+MakeOption(UpstreamCachePolicy& Value)
{
return std::make_shared<CachePolicyOption>(Value);
};
std::shared_ptr<LuaConfig::OptionValue>
-MakeOption(zen::ZenAuthConfig& Value)
+MakeOption(ZenAuthConfig& Value)
{
return std::make_shared<ZenAuthConfigOption>(Value);
};
std::shared_ptr<LuaConfig::OptionValue>
-MakeOption(zen::ZenObjectStoreConfig& Value)
+MakeOption(ZenObjectStoreConfig& Value)
{
return std::make_shared<ZenObjectStoreConfigOption>(Value);
};
@@ -660,11 +667,11 @@ ParseConfigFile(const std::filesystem::path& Path,
if (!OutputConfigFile.empty())
{
- std::filesystem::path WritePath(MakeSafeAbsolutePath(OutputConfigFile));
- zen::ExtendableStringBuilder<512> ConfigStringBuilder;
+ std::filesystem::path WritePath(MakeSafeAbsolutePath(OutputConfigFile));
+ ExtendableStringBuilder<512> ConfigStringBuilder;
LuaOptions.Print(ConfigStringBuilder, CmdLineResult);
- zen::BasicFile Output;
- Output.Open(WritePath, zen::BasicFile::Mode::kTruncate);
+ BasicFile Output;
+ Output.Open(WritePath, BasicFile::Mode::kTruncate);
Output.Write(ConfigStringBuilder.Data(), ConfigStringBuilder.Size(), 0);
}
}
@@ -737,7 +744,7 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
const char* DefaultHttp = "asio";
#if ZEN_WITH_HTTPSYS
- if (!zen::windows::IsRunningOnWine())
+ if (!windows::IsRunningOnWine())
{
DefaultHttp = "httpsys";
}
@@ -1334,7 +1341,7 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
}
catch (const std::exception& Ex)
{
- throw zen::OptionParseException(Ex.what());
+ throw OptionParseException(Ex.what(), options.help());
}
if (Result.count("help"))
@@ -1399,17 +1406,17 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
if (!BaseSnapshotDir.empty())
{
if (DataDir.empty())
- throw zen::OptionParseException("You must explicitly specify a data directory when specifying a base snapshot");
+ throw OptionParseException("'--snapshot-dir' requires '--data-dir'", options.help());
if (!IsDir(ServerOptions.BaseSnapshotDir))
- throw OptionParseException(fmt::format("Snapshot directory must be a directory: '{}", BaseSnapshotDir));
+ throw std::runtime_error(fmt::format("'--snapshot-dir' ('{}') must be a directory", BaseSnapshotDir));
}
if (OpenIdProviderUrl.empty() == false)
{
if (OpenIdClientId.empty())
{
- throw zen::OptionParseException("Invalid OpenID client ID");
+ throw OptionParseException("'--openid-provider-url' requires '--openid-client-id'", options.help());
}
ServerOptions.AuthConfig.OpenIdProviders.push_back(
@@ -1436,10 +1443,10 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
ValidateOptions(ServerOptions);
}
- catch (const zen::OptionParseException& e)
+ catch (const OptionParseException& e)
{
- ZEN_CONSOLE_ERROR("Invalid zenserver arguments: {}\n\n{}", e.what(), options.help());
-
+ ZEN_CONSOLE("{}\n", options.help());
+ ZEN_CONSOLE_ERROR("Invalid zenserver arguments: {}", e.what());
throw;
}