Skip to content

Commit 27c6569

Browse files
committed
Reduce duplication in error checking
Also, clean up logging and error messages. Now by default we log the API JSON responses in the log file, but not to stderr. Also, remove the JSON from the error messages because they flood the console with so much text it makes finding relevant information more difficult.
1 parent dfc6acb commit 27c6569

1 file changed

Lines changed: 48 additions & 53 deletions

File tree

base/cvd/cuttlefish/host/libs/web/android_build_api.cpp

Lines changed: 48 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,23 @@ struct CloseDir {
6565
void operator()(DIR* dir) { closedir(dir); }
6666
};
6767

68+
Result<Json::Value> GetResponseJson(const HttpResponse<Json::Value>& response,
69+
const bool allow_redirect = false) {
70+
// debug information in error responses floods stderr with too much text
71+
// logged at a level that still ends up in the log file
72+
LOG(DEBUG) << "API response data:\n" << response.data;
73+
const bool response_code_allowed =
74+
response.HttpSuccess() || (allow_redirect && response.HttpRedirect());
75+
CF_EXPECTF(std::move(response_code_allowed),
76+
"Error response from Android Build API - {}:{}\nCheck log file "
77+
"for full response",
78+
response.http_code, response.StatusDescription());
79+
CF_EXPECT(!response.data.isMember("error"),
80+
"Response was successful, but contains error information. Check "
81+
"log file for full response.");
82+
return response.data;
83+
}
84+
6885
} // namespace
6986

7087
DeviceBuild::DeviceBuild(std::string id, std::string target,
@@ -188,24 +205,20 @@ Result<std::optional<std::string>> AndroidBuildApi::LatestBuildId(
188205
android_build_url_->GetLatestBuildIdUrl(branch, target);
189206
auto response =
190207
CF_EXPECT(HttpGetToJson(http_client, url, CF_EXPECT(Headers())));
191-
const auto& json = response.data;
192-
CF_EXPECT(response.HttpSuccess(), "Error fetching the latest build of \""
193-
<< target << "\" on \"" << branch
194-
<< "\". The server response was \""
195-
<< json << "\", and code was "
196-
<< response.http_code);
197-
CF_EXPECT(!json.isMember("error"),
198-
"Response had \"error\" but had http success status. Received \""
199-
<< json << "\"");
200208

209+
const Json::Value json = CF_EXPECTF(GetResponseJson(response),
210+
"Error fetching last known good build "
211+
"id for:\nbranch \"{}\", target \"{}\"",
212+
branch, target);
201213
if (!json.isMember("builds")) {
202214
return std::nullopt;
203215
}
204-
CF_EXPECT(json["builds"].size() == 1,
205-
"Expected to receive 1 build for \""
206-
<< target << "\" on \"" << branch << "\", but received "
207-
<< json["builds"].size() << ". Full response:\n"
208-
<< json);
216+
217+
CF_EXPECTF(json["builds"].isArray() && json["builds"].size() == 1,
218+
"Expected to find a single latest build for branch \"{}\" and "
219+
"target \"{}\" in the response array, "
220+
"but found {}",
221+
branch, target, json["builds"].size());
209222
return CF_EXPECT(GetValue<std::string>(json["builds"][0], { "buildId" }));
210223
}
211224

@@ -214,15 +227,9 @@ Result<std::string> AndroidBuildApi::BuildStatus(const DeviceBuild& build) {
214227
android_build_url_->GetBuildStatusUrl(build.id, build.target);
215228
auto response =
216229
CF_EXPECT(HttpGetToJson(http_client, url, CF_EXPECT(Headers())));
217-
const auto& json = response.data;
218-
CF_EXPECT(response.HttpSuccess(),
219-
"Error fetching the status of \""
220-
<< build << "\". The server response was \"" << json
221-
<< "\", and code was " << response.http_code);
222-
CF_EXPECT(!json.isMember("error"),
223-
"Response had \"error\" but had http success status. Received \""
224-
<< json << "\"");
225-
230+
const Json::Value json = CF_EXPECT(GetResponseJson(response),
231+
"Error fetching build status for build:\n"
232+
<< build);
226233
return CF_EXPECT(GetValue<std::string>(json, { "buildAttemptStatus" }));
227234
}
228235

@@ -231,15 +238,9 @@ Result<std::string> AndroidBuildApi::ProductName(const DeviceBuild& build) {
231238
android_build_url_->GetProductNameUrl(build.id, build.target);
232239
auto response =
233240
CF_EXPECT(HttpGetToJson(http_client, url, CF_EXPECT(Headers())));
234-
const auto& json = response.data;
235-
CF_EXPECT(response.HttpSuccess(),
236-
"Error fetching the product name of \""
237-
<< build << "\". The server response was \"" << json
238-
<< "\", and code was " << response.http_code);
239-
CF_EXPECT(!json.isMember("error"),
240-
"Response had \"error\" but had http success status. Received \""
241-
<< json << "\"");
242-
241+
const Json::Value json = CF_EXPECT(GetResponseJson(response),
242+
"Error fetching product name for build:\n"
243+
<< build);
243244
return CF_EXPECT(GetValue<std::string>(json, { "target", "product" }));
244245
}
245246

@@ -248,29 +249,28 @@ Result<std::unordered_set<std::string>> AndroidBuildApi::Artifacts(
248249
const std::vector<std::string>& artifact_filenames) {
249250
std::string page_token = "";
250251
std::unordered_set<std::string> artifacts;
252+
251253
do {
252254
const std::string url = android_build_url_->GetArtifactUrl(
253255
build.id, build.target, artifact_filenames, page_token);
254256
auto response =
255257
CF_EXPECT(HttpGetToJson(http_client, url, CF_EXPECT(Headers())));
256-
const auto& json = response.data;
257-
CF_EXPECT(response.HttpSuccess(),
258-
"Error fetching the artifacts of \""
259-
<< build << "\". The server response was \"" << json
260-
<< "\", and code was " << response.http_code);
261-
CF_EXPECT(!json.isMember("error"),
262-
"Response had \"error\" but had http success status. Received \""
263-
<< json << "\"");
258+
259+
const Json::Value json = CF_EXPECT(GetResponseJson(response),
260+
"Error fetching artifacts list for:\n"
261+
<< build);
262+
for (const auto& artifact_json : json["artifacts"]) {
263+
artifacts.emplace(
264+
CF_EXPECT(GetValue<std::string>(artifact_json, {"name"})));
265+
}
266+
264267
if (json.isMember("nextPageToken")) {
265268
page_token = json["nextPageToken"].asString();
266269
} else {
267270
page_token = "";
268271
}
269-
for (const auto& artifact_json : json["artifacts"]) {
270-
artifacts.emplace(
271-
CF_EXPECT(GetValue<std::string>(artifact_json, {"name"})));
272-
}
273272
} while (!page_token.empty());
273+
274274
return artifacts;
275275
}
276276

@@ -304,15 +304,10 @@ Result<std::string> AndroidBuildApi::GetArtifactDownloadUrl(
304304
artifact);
305305
auto response = CF_EXPECT(
306306
HttpGetToJson(http_client, download_url_endpoint, CF_EXPECT(Headers())));
307-
const auto& json = response.data;
308-
CF_EXPECT(response.HttpSuccess() || response.HttpRedirect(),
309-
"Error fetching the url of \"" << artifact << "\" for \"" << build
310-
<< "\". The server response was \""
311-
<< json << "\", and code was "
312-
<< response.http_code);
313-
CF_EXPECT(!json.isMember("error"),
314-
"Response had \"error\" but had http success status. "
315-
<< "Received \"" << json << "\"");
307+
const Json::Value json =
308+
CF_EXPECTF(GetResponseJson(response, /* allow redirect response */ true),
309+
"Error fetching download URL for \"{}\" from build ID \"{}\"",
310+
artifact, build.id);
316311
return CF_EXPECT(GetValue<std::string>(json, { "signedUrl" }));
317312
}
318313

0 commit comments

Comments
 (0)