diff --git a/include/siadrive_api/siaapi.h b/include/siadrive_api/siaapi.h index 46e2c58..c0a1fc4 100644 --- a/include/siadrive_api/siaapi.h +++ b/include/siadrive_api/siaapi.h @@ -43,10 +43,11 @@ protected: class SIADRIVE_EXPORTABLE CSiaApi { public: - enum class _SiaApiError + enum class _SiaApiErrorCode { Success, NotImplemented, + NotConnected, RequestError, WalletExists, WalletLocked, @@ -133,10 +134,10 @@ public: virtual void Refresh(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig); public: - _SiaApiError Create(const _SiaSeedLanguage& seedLanguage, SString& seed); - _SiaApiError Restore(const SString& seed); - _SiaApiError Lock(); - _SiaApiError Unlock(const SString& password); + CSiaError<_SiaApiErrorCode> Create(const _SiaSeedLanguage& seedLanguage, SString& seed); + CSiaError<_SiaApiErrorCode> Restore(const SString& seed); + CSiaError<_SiaApiErrorCode> Lock(); + CSiaError<_SiaApiErrorCode> Unlock(const SString& password); }; class SIADRIVE_EXPORTABLE _CSiaRenter : @@ -176,12 +177,12 @@ public: void Refresh(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig); public: - _SiaApiError FileExists(const SString& siaPath, bool& exists) const; - _SiaApiError DownloadFile(const SString& siaPath, const SString& location) const; - _SiaApiError GetFileTree(std::shared_ptr<_CSiaFileTree>& siaFileTree) const; + CSiaError<_SiaApiErrorCode> FileExists(const SString& siaPath, bool& exists) const; + CSiaError<_SiaApiErrorCode> DownloadFile(const SString& siaPath, const SString& location) const; + CSiaError<_SiaApiErrorCode> GetFileTree(std::shared_ptr<_CSiaFileTree>& siaFileTree) const; _SiaRenterAllowance GetAllowance() const; - _SiaApiError SetAllowance(const _SiaRenterAllowance& renterAllowance); - _SiaApiError RefreshFileTree( ); + CSiaError<_SiaApiErrorCode> SetAllowance(const _SiaRenterAllowance& renterAllowance); + CSiaError<_SiaApiErrorCode> RefreshFileTree( ); }; class SIADRIVE_EXPORTABLE _CSiaConsensus : @@ -233,7 +234,8 @@ public: SiaHostConfig GetHostConfig() const; }; -typedef CSiaApi::_SiaApiError SiaApiError; +typedef CSiaApi::_SiaApiErrorCode SiaApiErrorCode; +typedef CSiaError SiaApiError; typedef CSiaApi::_SiaSeedLanguage SiaSeedLanguage; typedef CSiaApi::_CSiaWallet CSiaWallet; typedef CSiaApi::_CSiaRenter CSiaRenter; diff --git a/include/siadrive_api/siacommon.h b/include/siadrive_api/siacommon.h index a3cae69..b6cf58b 100644 --- a/include/siadrive_api/siacommon.h +++ b/include/siadrive_api/siacommon.h @@ -98,6 +98,36 @@ get_access:\ set_access:\ type Set##name(const type& value) { json_doc[#name] = value; return value; } +template +class CSiaError +{ +public: + CSiaError() + { + SetCode(T::Success); + } + + CSiaError(const T& t) + { + SetCode(t); + } + + CSiaError(const T& code, const SString& reason) + { + SetCode(code); + SetReason(reason); + } + +public: + Property(T, Code, public, private) + Property(SString, Reason, public, private) + +public: + operator bool() { return GetCode() == T::Success; } + operator bool() const { return GetCode() == T::Success; } + CSiaError& operator=(const T& code) { SetCode(code); return *this; } +}; + typedef struct { SString HostName; @@ -107,7 +137,7 @@ typedef struct template inline bool ApiSuccess(const T& t) { - return t == T::Success; + return static_cast(t); } typedef ttmath::UInt<256> Hastings; diff --git a/include/siadrive_api/siacurl.h b/include/siadrive_api/siacurl.h index 06a2a1e..2d4e83c 100644 --- a/include/siadrive_api/siacurl.h +++ b/include/siadrive_api/siacurl.h @@ -9,7 +9,7 @@ NS_BEGIN(Api) class SIADRIVE_EXPORTABLE CSiaCurl { public: - enum class _SiaCurlError + enum class _SiaCurlErrorCode { Success, ServerVersionMismatch, @@ -36,23 +36,23 @@ public: static SString UrlEncode(const SString& data, const bool& allowSlash = false); private: - static _SiaCurlError CheckApiError(const json& result); - static _SiaCurlError CheckHttpError(const std::string& result); + static SString CSiaCurl::GetApiErrorMessage(const json& result); private: std::string ConstructPath(const SString& relativePath) const; - _SiaCurlError _Get(const SString& path, const _HttpParameters& parameters, json& response) const; - bool CheckVersion(_SiaCurlError& error) const; - _SiaCurlError ProcessResponse(const int& res, const int& httpCode, const std::string& result, json& response) const; + CSiaError<_SiaCurlErrorCode> _Get(const SString& path, const _HttpParameters& parameters, json& response) const; + bool CheckVersion(CSiaError<_SiaCurlErrorCode>& error) const; + CSiaError<_SiaCurlErrorCode> ProcessResponse(const int& res, const int& httpCode, const std::string& result, json& response) const; public: SString GetServerVersion() const; - _SiaCurlError Get(const SString& path, json& result) const; - _SiaCurlError Get(const SString& path, const _HttpParameters& parameters, json& result) const; - _SiaCurlError Post(const SString& path, const _HttpParameters& parameters, json& response) const; + CSiaError<_SiaCurlErrorCode> Get(const SString& path, json& result) const; + CSiaError<_SiaCurlErrorCode> Get(const SString& path, const _HttpParameters& parameters, json& result) const; + CSiaError<_SiaCurlErrorCode> Post(const SString& path, const _HttpParameters& parameters, json& response) const; }; -typedef CSiaCurl::_SiaCurlError SiaCurlError; +typedef CSiaCurl::_SiaCurlErrorCode SiaCurlErrorCode; +typedef CSiaError SiaCurlError; typedef CSiaCurl::_HttpParameters HttpParameters; NS_END(2) diff --git a/include/siadrive_api/uploadmanager.h b/include/siadrive_api/uploadmanager.h index e49d2aa..f8c54c9 100644 --- a/include/siadrive_api/uploadmanager.h +++ b/include/siadrive_api/uploadmanager.h @@ -26,7 +26,7 @@ public: Error }; - enum class _UploadError + enum class _UploadErrorCode { Success, SourceFileNotFound, @@ -68,12 +68,13 @@ public: public: _UploadStatus GetUploadStatus(const SString& siaPath); - _UploadError AddOrUpdate(const SString& siaPath, SString filePath); - _UploadError Remove(const SString& siaPath); + CSiaError<_UploadErrorCode> AddOrUpdate(const SString& siaPath, SString filePath); + CSiaError<_UploadErrorCode> Remove(const SString& siaPath); }; -typedef Sia::Api::CUploadManager::_UploadStatus UploadStatus; -typedef Sia::Api::CUploadManager::_UploadError UploadError; +typedef CUploadManager::_UploadStatus UploadStatus; +typedef CUploadManager::_UploadErrorCode UploadErrorCode; +typedef CSiaError UploadError; // Event Notifications class CreatingTemporarySiaDriveFile : @@ -388,7 +389,7 @@ public: private: const SString _siaPath; const SString _filePath; - const SiaCurlError _curlError = SiaCurlError::Success; + const SiaCurlError _curlError; public: virtual SString GetSingleLineMessage() const override diff --git a/src/siadrive_api/siacurl.cpp b/src/siadrive_api/siacurl.cpp index dcbf25d..59f6eca 100644 --- a/src/siadrive_api/siacurl.cpp +++ b/src/siadrive_api/siacurl.cpp @@ -35,21 +35,13 @@ SString CSiaCurl::UrlEncode(const SString& data, const bool& allowSlash) return ret; } -SiaCurlError CSiaCurl::CheckApiError(const json& result) +SString CSiaCurl::GetApiErrorMessage(const json& result) { - SiaCurlError ret = SiaCurlError::Success; + + SString ret; if (result.find("message") != result.end()) { - ret = SiaCurlError::UnknownFailure; - - const std::string msg = result["message"].get(); - if ((msg.length() >= 3)) - { - if ((msg.substr(0, 3) == "404")) - { - ret = SiaCurlError::HttpError; - } - } + ret = result["message"].get(); } return ret; @@ -61,40 +53,29 @@ std::string CSiaCurl::ConstructPath(const SString& relativePath) const return ret; } -SiaCurlError CSiaCurl::CheckHttpError(const std::string& result) -{ - if (result.length() && ((result.length() < 2) || (result[0] != '{'))) - { - return SiaCurlError::HttpError; - } - - return SiaCurlError::Success; -} - SiaCurlError CSiaCurl::ProcessResponse(const int& res, const int& httpCode, const std::string& result, json& response) const { - SiaCurlError ret; + SiaCurlError ret; if ((res == CURLE_OK) && ((httpCode >= 200) && (httpCode <300))) { - ret = CheckHttpError(result); - if (ApiSuccess(ret)) - { - ret = (result.length() ? CheckApiError((response = json::parse(result.c_str()))) : SiaCurlError::Success); - } + if (result.length()) + { + response = json::parse(result.c_str()); + } } else { if ((res == CURLE_COULDNT_RESOLVE_HOST) || (res == CURLE_COULDNT_CONNECT)) { - ret = SiaCurlError::NoResponse; + ret = SiaCurlErrorCode::NoResponse; } else if (httpCode) { - ret = SiaCurlError::HttpError; + ret = { SiaCurlErrorCode::HttpError, GetApiErrorMessage(result) }; } else { - ret = SiaCurlError::UnknownFailure; + ret = { SiaCurlErrorCode::UnknownFailure, "Unknown curl error" }; } } @@ -140,14 +121,14 @@ SiaCurlError CSiaCurl::_Get(const SString& path, const HttpParameters& parameter bool CSiaCurl::CheckVersion(SiaCurlError& error) const { - error = SiaCurlError::InvalidRequiredVersion; + error = SiaCurlErrorCode::InvalidRequiredVersion; if (GetHostConfig().RequiredVersion.Length()) { - error = SiaCurlError::NoResponse; + error = SiaCurlErrorCode::NoResponse; const SString serverVersion = GetServerVersion(); if (serverVersion.Length()) { - error = (serverVersion == GetHostConfig().RequiredVersion) ? SiaCurlError::Success : SiaCurlError::ServerVersionMismatch; + error = (serverVersion == GetHostConfig().RequiredVersion) ? SiaCurlErrorCode::Success : SiaCurlErrorCode::ServerVersionMismatch; } } diff --git a/src/siadrive_api/siarenter.cpp b/src/siadrive_api/siarenter.cpp index 153f769..cb79ac8 100644 --- a/src/siadrive_api/siarenter.cpp +++ b/src/siadrive_api/siarenter.cpp @@ -103,7 +103,7 @@ void CSiaApi::_CSiaRenter::Refresh(const CSiaCurl& siaCurl, CSiaDriveConfig* sia std::uint32_t totalProgress = std::accumulate(std::next(fileList.begin()), fileList.end(), fileList[0]->GetUploadProgress(), [](const std::uint32_t& progress, const CSiaFilePtr& file) { return progress + min(100, file->GetUploadProgress()); - }) / fileList.size(); + }) / static_cast(fileList.size()); SetTotalUsedBytes(total); SetTotalUploadProgress(totalProgress); @@ -135,10 +135,11 @@ void CSiaApi::_CSiaRenter::Refresh(const CSiaCurl& siaCurl, CSiaDriveConfig* sia SiaApiError CSiaApi::_CSiaRenter::RefreshFileTree( ) { - SiaApiError ret = SiaApiError::RequestError; + SiaApiError ret; CSiaFileTreePtr tempTree(new CSiaFileTree(GetSiaCurl(), &GetSiaDriveConfig())); - json result; - if (ApiSuccess(GetSiaCurl().Get(L"/renter/files", result))) + json result; + SiaCurlError cerror = GetSiaCurl().Get(L"/renter/files", result); + if (ApiSuccess(cerror)) { tempTree->BuildTree(result); { @@ -146,6 +147,10 @@ SiaApiError CSiaApi::_CSiaRenter::RefreshFileTree( ) _fileTree = tempTree; } } + else + { + ret = { SiaApiErrorCode::RequestError, cerror.GetReason() }; + } return ret; } @@ -158,16 +163,18 @@ SiaApiError CSiaApi::_CSiaRenter::FileExists(const SString& siaPath, bool& exist { exists = siaFileTree->FileExists(siaPath); } + return ret; } SiaApiError CSiaApi::_CSiaRenter::DownloadFile(const SString& siaPath, const SString& location) const { - SiaApiError ret = SiaApiError::RequestError; + SiaApiError ret; json result; - if (ApiSuccess(GetSiaCurl().Get(L"/renter/download/" + siaPath, { { L"destination", location } }, result))) + auto cerror = GetSiaCurl().Get(L"/renter/download/" + siaPath, { { L"destination", location } }, result); + if (!ApiSuccess(cerror)) { - ret = SiaApiError::Success; + ret = { SiaApiErrorCode::RequestError, cerror.GetReason() }; } return ret; @@ -181,7 +188,7 @@ SiaApiError CSiaApi::_CSiaRenter::GetFileTree(CSiaFileTreePtr& siaFileTree) cons siaFileTree.reset(new CSiaFileTree(GetSiaCurl(), &GetSiaDriveConfig())); } - return SiaApiError::Success; + return SiaApiErrorCode::Success; } SiaRenterAllowance CSiaApi::_CSiaRenter::GetAllowance() const @@ -191,18 +198,19 @@ SiaRenterAllowance CSiaApi::_CSiaRenter::GetAllowance() const SiaApiError CSiaApi::_CSiaRenter::SetAllowance(const SiaRenterAllowance& renterAllowance) { - SiaApiError ret = SiaApiError::RequestError; + SiaApiError ret; json result; - if (ApiSuccess(GetSiaCurl().Post(L"/renter", + auto cerror = GetSiaCurl().Post(L"/renter", { { "funds", SiaCurrencyToHastingsString(renterAllowance.Funds) }, { "hosts", SString::FromUInt64(renterAllowance.Hosts) }, { "period", SString::FromUInt64(renterAllowance.Period) }, { "renewwindow", SString::FromUInt64 (renterAllowance.RenewWindowInBlocks) } - }, result))) + }, result); + if (!ApiSuccess(cerror)) { - ret = SiaApiError::Success; + ret = { SiaApiErrorCode::RequestError, cerror.GetReason() }; } return ret; diff --git a/src/siadrive_api/siawallet.cpp b/src/siadrive_api/siawallet.cpp index d780b51..73c6e39 100644 --- a/src/siadrive_api/siawallet.cpp +++ b/src/siadrive_api/siawallet.cpp @@ -83,20 +83,26 @@ void CSiaApi::_CSiaWallet::Refresh(const CSiaCurl& siaCurl, CSiaDriveConfig* sia SiaApiError CSiaApi::_CSiaWallet::Create(const SiaSeedLanguage& seedLanguage, SString& seed) { - SiaApiError error = SiaApiError::RequestError; + SiaApiError error = SiaApiErrorCode::NotConnected; if (GetConnected()) { - error = SiaApiError::WalletExists; - if (!GetCreated()) + if (GetCreated()) + { + error = SiaApiErrorCode::WalletExists; + } + else { - error = SiaApiError::RequestError; json result; SiaCurlError cerror = GetSiaCurl().Post(L"/wallet/init", { {L"dictionary", SeedLangToString(seedLanguage)} }, result); if (ApiSuccess(cerror)) { - error = SiaApiError::Success; + error = SiaApiErrorCode::Success; seed = result["primaryseed"].get(); } + else + { + error = { SiaApiErrorCode::RequestError, cerror.GetReason() }; + } } } @@ -105,24 +111,26 @@ SiaApiError CSiaApi::_CSiaWallet::Create(const SiaSeedLanguage& seedLanguage, SS SiaApiError CSiaApi::_CSiaWallet::Restore(const SString& seed) { - SiaApiError error = SiaApiError::NotImplemented; + SiaApiError error = SiaApiErrorCode::NotImplemented; // TODO Future enhancement return error; } SiaApiError CSiaApi::_CSiaWallet::Lock() { - SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiError::WalletLocked : SiaApiError::Success) : SiaApiError::WalletNotCreated; + SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiErrorCode::WalletLocked : SiaApiErrorCode::Success) : SiaApiErrorCode::WalletNotCreated; if (ApiSuccess(error)) { - error = SiaApiError::RequestError; - json result; SiaCurlError cerror = GetSiaCurl().Post(L"/wallet/lock", {}, result); if (ApiSuccess(cerror)) { - error = SiaApiError::Success; + error = SiaApiErrorCode::Success; } + else + { + error = { SiaApiErrorCode::RequestError, cerror.GetReason() }; + } } return error; @@ -130,17 +138,19 @@ SiaApiError CSiaApi::_CSiaWallet::Lock() SiaApiError CSiaApi::_CSiaWallet::Unlock(const SString& password) { - SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiError::Success : SiaApiError::WalletUnlocked) : SiaApiError::WalletNotCreated; + SiaApiError error = GetCreated() ? (GetLocked() ? SiaApiErrorCode::Success : SiaApiErrorCode::WalletUnlocked) : SiaApiErrorCode::WalletNotCreated; if (ApiSuccess(error)) { - error = SiaApiError::RequestError; - json result; SiaCurlError cerror = GetSiaCurl().Post(L"/wallet/unlock", { {L"encryptionpassword", password} }, result); if (ApiSuccess(cerror)) { - error = SiaApiError::Success; + error = SiaApiErrorCode::Success; } + else + { + error = { SiaApiErrorCode::RequestError, cerror.GetReason() }; + } } return error; diff --git a/src/siadrive_api/uploadmanager.cpp b/src/siadrive_api/uploadmanager.cpp index f45711a..2adb6e0 100644 --- a/src/siadrive_api/uploadmanager.cpp +++ b/src/siadrive_api/uploadmanager.cpp @@ -387,7 +387,7 @@ UploadStatus CUploadManager::GetUploadStatus(const SString& siaPath) UploadError CUploadManager::AddOrUpdate(const SString& siaPath, SString filePath) { - UploadError ret = UploadError::Success; + UploadError ret; // Relative to absolute and grab parent folder of source FilePath rootPath = filePath; @@ -439,26 +439,26 @@ UploadError CUploadManager::AddOrUpdate(const SString& siaPath, SString filePath else { CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DatabaseInsertFailed(siaPath, filePath, insert.getErrorMsg()))); - ret = UploadError::DatabaseError; + ret = UploadErrorCode::DatabaseError; } } catch (SQLite::Exception e) { CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DatabaseExceptionOccurred("AddOrUpdate(insert)", e))); - ret = UploadError::DatabaseError; + ret = { UploadErrorCode::DatabaseError, e.getErrorStr() }; } } } catch (SQLite::Exception e) { CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DatabaseExceptionOccurred("AddOrUpdate(query)", e))); - ret = UploadError::DatabaseError; + ret = { UploadErrorCode::DatabaseError, e.getErrorStr() }; } } else { CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(SourceFileNotFound(siaPath, filePath))); - ret = UploadError::SourceFileNotFound; + ret = UploadErrorCode::SourceFileNotFound; } return ret; @@ -466,7 +466,7 @@ UploadError CUploadManager::AddOrUpdate(const SString& siaPath, SString filePath UploadError CUploadManager::Remove(const SString& siaPath) { - UploadError ret = UploadError::Success; + UploadError ret; bool remove = false; SString siaDriveFilePath; try @@ -506,7 +506,7 @@ UploadError CUploadManager::Remove(const SString& siaPath) catch (SQLite::Exception e) { CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DatabaseExceptionOccurred("Remove", e))); - ret = UploadError::DatabaseError; + ret = { UploadErrorCode::DatabaseError, e.getErrorStr() }; } if (remove)