Skip to content

Commit a0d41a7

Browse files
authored
CXXCBC-632: Do not assume Analytics will always send meta fields in response (#699)
"requestID", "clientContextID" and "metrics" might be missing. For example, the following payload might be sent with status 503: { "errors": [ { "code": 23000, "msg": "Analytics Service is temporarily unavailable" } ], "status": "fatal" }
1 parent 450c9e0 commit a0d41a7

File tree

1 file changed

+23
-17
lines changed

1 file changed

+23
-17
lines changed

core/operations/document_analytics.cxx

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,16 @@ analytics_request::make_response(error_context::analytics&& ctx,
116116
response.ctx.ec = errc::common::parsing_failure;
117117
return response;
118118
}
119-
response.meta.request_id = payload.at("requestID").get_string();
120-
response.meta.client_context_id = payload.at("clientContextID").get_string();
121-
if (response.ctx.client_context_id != response.meta.client_context_id) {
122-
CB_LOG_WARNING(R"(unexpected clientContextID returned by service: "{}", expected "{}")",
123-
response.meta.client_context_id,
124-
response.ctx.client_context_id);
119+
if (const auto* i = payload.find("requestID"); i != nullptr) {
120+
response.meta.request_id = i->get_string();
121+
}
122+
if (const auto* i = payload.find("clientContextID"); i != nullptr) {
123+
response.meta.client_context_id = i->get_string();
124+
if (response.ctx.client_context_id != response.meta.client_context_id) {
125+
CB_LOG_WARNING(R"(unexpected clientContextID returned by service: "{}", expected "{}")",
126+
response.meta.client_context_id,
127+
response.ctx.client_context_id);
128+
}
125129
}
126130
if (auto& status_prop = payload.at("status"); status_prop.is_string()) {
127131
const auto& status = status_prop.get_string();
@@ -154,17 +158,19 @@ analytics_request::make_response(error_context::analytics&& ctx,
154158
response.meta.signature = couchbase::core::utils::json::generate(*s);
155159
}
156160

157-
const tao::json::value& metrics = payload.at("metrics");
158-
response.meta.metrics.result_count = metrics.at("resultCount").get_unsigned();
159-
response.meta.metrics.result_size = metrics.at("resultSize").get_unsigned();
160-
response.meta.metrics.elapsed_time =
161-
utils::parse_duration(metrics.at("elapsedTime").get_string());
162-
response.meta.metrics.execution_time =
163-
utils::parse_duration(metrics.at("executionTime").get_string());
164-
response.meta.metrics.processed_objects = metrics.at("processedObjects").get_unsigned();
165-
response.meta.metrics.error_count = metrics.optional<std::uint64_t>("errorCount").value_or(0);
166-
response.meta.metrics.warning_count =
167-
metrics.optional<std::uint64_t>("warningCount").value_or(0);
161+
if (const auto* metrics = payload.find("metrics"); metrics != nullptr) {
162+
response.meta.metrics.result_count = metrics->at("resultCount").get_unsigned();
163+
response.meta.metrics.result_size = metrics->at("resultSize").get_unsigned();
164+
response.meta.metrics.elapsed_time =
165+
utils::parse_duration(metrics->at("elapsedTime").get_string());
166+
response.meta.metrics.execution_time =
167+
utils::parse_duration(metrics->at("executionTime").get_string());
168+
response.meta.metrics.processed_objects = metrics->at("processedObjects").get_unsigned();
169+
response.meta.metrics.error_count =
170+
metrics->optional<std::uint64_t>("errorCount").value_or(0);
171+
response.meta.metrics.warning_count =
172+
metrics->optional<std::uint64_t>("warningCount").value_or(0);
173+
}
168174

169175
if (const auto* e = payload.find("errors"); e != nullptr) {
170176
for (const auto& err : e->get_array()) {

0 commit comments

Comments
 (0)