diff options
| author | Dan Engelbrecht <[email protected]> | 2024-01-22 13:22:21 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-01-22 13:22:21 +0100 |
| commit | d0630968516f31a9c6ebc9a5643b7cd19f6cb184 (patch) | |
| tree | a2bbf71b93f0254415f13cebcb41ac9d808db312 | |
| parent | jobqueue - allow multiple threads to report progress/messages (#635) (diff) | |
| download | zen-d0630968516f31a9c6ebc9a5643b7cd19f6cb184.tar.xz zen-d0630968516f31a9c6ebc9a5643b7cd19f6cb184.zip | |
improved errors from jupiter upstream (#636)
* get more detailed error messages from jupiter upstream
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | src/zenhttp/httpserver.cpp | 11 | ||||
| -rw-r--r-- | src/zenserver/projectstore/jupiterremoteprojectstore.cpp | 27 | ||||
| -rw-r--r-- | src/zenserver/upstream/jupiter.cpp | 50 |
4 files changed, 83 insertions, 6 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e98a1bff..0c73260c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## - Improvement: Removed use of <random> in stats, for better performance (runtime as well as build) - Improvement: Separated cache RPC handling code from general structured cache HTTP code +- Improvement: Get more detailed information on Jupiter upstream errors - Bugfix: RPC recording would not release memory as early as intended which resulted in memory buildup during long recording sessions. Previously certain memory was only released when recording stopped, now it gets released immediately when a segment is complete and written to disk. - Bugfix: File log format now contains dates again (PR #631) - Bugfix: Jobqueue - Allow multiple threads to report progress/messages (oplog import/export) diff --git a/src/zenhttp/httpserver.cpp b/src/zenhttp/httpserver.cpp index 3270855ad..dcbeac907 100644 --- a/src/zenhttp/httpserver.cpp +++ b/src/zenhttp/httpserver.cpp @@ -94,6 +94,7 @@ MapContentTypeToString(HttpContentType ContentType) static constinit uint32_t HashBinary = HashStringDjb2("application/octet-stream"sv); static constinit uint32_t HashJson = HashStringDjb2("json"sv); static constinit uint32_t HashApplicationJson = HashStringDjb2("application/json"sv); +static constinit uint32_t HashApplicationProblemJson = HashStringDjb2("application/problem+json"sv); static constinit uint32_t HashYaml = HashStringDjb2("yaml"sv); static constinit uint32_t HashTextYaml = HashStringDjb2("text/yaml"sv); static constinit uint32_t HashText = HashStringDjb2("text/plain"sv); @@ -132,6 +133,7 @@ struct HashedTypeEntry {HashCompactBinaryPackageOffer, HttpContentType::kCbPackageOffer}, {HashJson, HttpContentType::kJSON}, {HashApplicationJson, HttpContentType::kJSON}, + {HashApplicationProblemJson, HttpContentType::kJSON}, {HashYaml, HttpContentType::kYAML}, {HashTextYaml, HttpContentType::kYAML}, {HashText, HttpContentType::kText}, @@ -156,7 +158,14 @@ ParseContentTypeImpl(const std::string_view& ContentTypeString) { if (!ContentTypeString.empty()) { - const uint32_t CtHash = HashStringDjb2(ContentTypeString); + size_t ContentEnd = ContentTypeString.find(';'); + if (ContentEnd == std::string_view::npos) + { + ContentEnd = ContentTypeString.length(); + } + std::string_view ContentString(ContentTypeString.substr(0, ContentEnd)); + + const uint32_t CtHash = HashStringDjb2(ContentString); if (auto It = std::lower_bound(std::begin(TypeHashTable), std::end(TypeHashTable), diff --git a/src/zenserver/projectstore/jupiterremoteprojectstore.cpp b/src/zenserver/projectstore/jupiterremoteprojectstore.cpp index fbc3c8e16..9d8f6c17b 100644 --- a/src/zenserver/projectstore/jupiterremoteprojectstore.cpp +++ b/src/zenserver/projectstore/jupiterremoteprojectstore.cpp @@ -256,6 +256,28 @@ private: { std::string Text; int32_t ErrorCode = 0; + if (Response.ErrorCode != 0 || !Response.Success) + { + if (Response.Response) + { + HttpContentType ContentType = Response.Response.GetContentType(); + if (ContentType == ZenContentType::kText || ContentType == ZenContentType::kJSON) + { + ExtendableStringBuilder<256> SB; + SB.Append("\n"); + SB.Append(std::string_view(reinterpret_cast<const std::string::value_type*>(Response.Response.GetData()), + Response.Response.GetSize())); + Text = SB.ToString(); + } + else if (ContentType == ZenContentType::kCbObject) + { + ExtendableStringBuilder<256> SB; + SB.Append("\n"); + CompactBinaryToJson(Response.Response.GetView(), SB); + Text = SB.ToString(); + } + } + } if (Response.ErrorCode != 0) { ErrorCode = Response.ErrorCode; @@ -263,11 +285,6 @@ private: else if (!Response.Success) { ErrorCode = gsl::narrow<int32_t>(HttpResponseCode::InternalServerError); - if (Response.Response.GetContentType() == ZenContentType::kText) - { - Text = - std::string(reinterpret_cast<const std::string::value_type*>(Response.Response.GetData()), Response.Response.GetSize()); - } } return {.ErrorCode = ErrorCode, .ElapsedSeconds = Response.ElapsedSeconds, .Reason = Response.Reason, .Text = Text}; } diff --git a/src/zenserver/upstream/jupiter.cpp b/src/zenserver/upstream/jupiter.cpp index a67c497ad..e4d45e316 100644 --- a/src/zenserver/upstream/jupiter.cpp +++ b/src/zenserver/upstream/jupiter.cpp @@ -157,6 +157,31 @@ namespace detail { return Response; } + static std::optional<zen::HttpContentType> TryGetContentType(const cpr::Response& Response) + { + if (auto It = Response.header.find("Content-Type"); It != Response.header.end()) + { + zen::HttpContentType ContentType = zen::ParseContentType(It->second); + if (ContentType != zen::HttpContentType::kUnknownContentType) + { + return ContentType; + } + } + return {}; + } + + static IoBuffer MakeBufferFromResponseIfKnownFormat(const cpr::Response& Response) + { + std::optional<zen::HttpContentType> ContentType = TryGetContentType(Response); + if (ContentType) + { + IoBuffer Buffer = IoBufferBuilder::MakeCloneFromMemory(Response.text.data(), Response.text.size()); + Buffer.SetContentType(ContentType.value()); + return Buffer; + } + return {}; + } + } // namespace detail CloudCacheSession::CloudCacheSession(CloudCacheClient* CacheClient) : m_Log(CacheClient->Logger()), m_CacheClient(CacheClient) @@ -203,6 +228,7 @@ CloudCacheSession::GetRef(std::string_view Namespace, std::string_view BucketId, } else { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::GetRef failed GET. " "Elapsed: {} s, " @@ -252,6 +278,7 @@ CloudCacheSession::GetBlob(std::string_view Namespace, const IoHash& Key) } else { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::GetBlob failed GET. " "Elapsed: {} s, " @@ -305,6 +332,12 @@ CloudCacheSession::GetCompressedBlob(std::string_view Namespace, const IoHash& K } else { + std::optional<zen::HttpContentType> ContentType = detail::TryGetContentType(Response); + if (ContentType.has_value()) + { + Result.Response = std::move(Payload); + Result.Response.SetContentType(ContentType.value()); + } ZEN_WARN( "CloudCacheSession::GetCompressedBlob failed GET. " "Elapsed: {} s, " @@ -362,6 +395,12 @@ CloudCacheSession::GetInlineBlob(std::string_view Namespace, } else { + std::optional<zen::HttpContentType> ContentType = detail::TryGetContentType(Response); + if (ContentType.has_value()) + { + Result.Response = std::move(Payload); + Result.Response.SetContentType(ContentType.value()); + } ZEN_WARN( "CloudCacheSession::GetInlineBlob failed GET. " "Elapsed: {} s, " @@ -423,6 +462,7 @@ CloudCacheSession::GetObject(std::string_view Namespace, const IoHash& Key) } else { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::GetObject failed GET. " "Elapsed: {} s, " @@ -490,6 +530,7 @@ CloudCacheSession::PutRef(std::string_view Namespace, std::string_view BucketId, } else { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::PutRef failed PUT. " "Elapsed: {} s, " @@ -559,6 +600,7 @@ CloudCacheSession::FinalizeRef(std::string_view Namespace, std::string_view Buck } else { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::FinalizeRef failed PUT. " "Elapsed: {} s, " @@ -611,6 +653,7 @@ CloudCacheSession::PutBlob(std::string_view Namespace, const IoHash& Key, IoBuff CloudCacheResult Result = detail::ConvertResponse(Response); if (!Result.Success) { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::PutBlob failed PUT. " "Elapsed: {} s, " @@ -677,6 +720,7 @@ CloudCacheSession::PutCompressedBlob(std::string_view Namespace, const IoHash& K CloudCacheResult Result = detail::ConvertResponse(Response); if (!Result.Success) { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::PutCompressedBlob failed PUT. " "Elapsed: {} s, " @@ -735,6 +779,7 @@ CloudCacheSession::PutCompressedBlob(std::string_view Namespace, const IoHash& K CloudCacheResult Result = detail::ConvertResponse(Response); if (!Result.Success) { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::PutCompressedBlob failed PUT. " "Elapsed: {} s, " @@ -784,6 +829,7 @@ CloudCacheSession::PutObject(std::string_view Namespace, const IoHash& Key, IoBu CloudCacheResult Result = detail::ConvertResponse(Response); if (!Result.Success) { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::PutObject failed PUT. " "Elapsed: {} s, " @@ -833,6 +879,7 @@ CloudCacheSession::RefExists(std::string_view Namespace, std::string_view Bucket CloudCacheResult Result = detail::ConvertResponse(Response); if (!Result.Success) { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::RefExists failed PUT. " "Elapsed: {} s, " @@ -888,6 +935,7 @@ CloudCacheSession::GetObjectReferences(std::string_view Namespace, const IoHash& } else { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::GetObjectReferences failed PUT. " "Elapsed: {} s, " @@ -996,6 +1044,7 @@ CloudCacheSession::CacheTypeExists(std::string_view Namespace, std::string_view CloudCacheResult Result = detail::ConvertResponse(Response); if (!Result.Success) { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::CacheTypeExists failed GET. " "Elapsed: {} s, " @@ -1061,6 +1110,7 @@ CloudCacheSession::CacheTypeExists(std::string_view Namespace, std::string_view } else { + Result.Response = detail::MakeBufferFromResponseIfKnownFormat(Response); ZEN_WARN( "CloudCacheSession::CacheTypeExists failed GET. " "Elapsed: {} s, " |