From 2785388cf8c9cf74dbd2f203659dec6748d033cf Mon Sep 17 00:00:00 2001 From: Igor Peshansky Date: Sat, 24 Feb 2018 16:54:26 -0500 Subject: [PATCH 1/3] Handle error response codes to HTTP requests. --- src/api_server.cc | 26 ++++++++++++++++++++------ src/docker.cc | 8 ++++++++ src/environment.cc | 11 ++++++++++- src/format.cc | 13 +++++++++++++ src/format.h | 4 ++++ src/kubernetes.cc | 8 ++++++++ 6 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/api_server.cc b/src/api_server.cc index d2341a05..c93cf9b4 100644 --- a/src/api_server.cc +++ b/src/api_server.cc @@ -76,7 +76,8 @@ class MetadataReporter { // Send the given set of metadata. void SendMetadata( - std::map&& metadata); + std::map&& metadata) + throw (boost::system::system_error); const MetadataAgent& agent_; Environment environment_; @@ -171,9 +172,13 @@ void MetadataReporter::ReportMetadata() { if (agent_.config_.VerboseLogging()) { LOG(INFO) << "Sending metadata request to server"; } - SendMetadata(agent_.GetMetadataMap()); - if (agent_.config_.VerboseLogging()) { - LOG(INFO) << "Metadata request sent successfully"; + try { + SendMetadata(agent_.GetMetadataMap()); + if (agent_.config_.VerboseLogging()) { + LOG(INFO) << "Metadata request sent successfully"; + } + } catch (const boost::system::system_error& e) { + LOG(ERROR) << "Unsuccessful: " << e.what(); } std::this_thread::sleep_for(period_); } @@ -185,7 +190,8 @@ namespace { void SendMetadataRequest(std::vector&& entries, const std::string& endpoint, const std::string& auth_header, - bool verbose_logging) { + bool verbose_logging) + throw (boost::system::system_error) { json::value update_metadata_request = json::object({ {"entries", json::array(std::move(entries))}, }); @@ -204,6 +210,13 @@ void SendMetadataRequest(std::vector&& entries, request << boost::network::header("Authorization", auth_header); request << boost::network::body(request_body); http::client::response response = client.post(request); + if (status(response) != 200) { + throw boost::system::system_error( + boost::system::errc::make_error_code(boost::system::errc::not_connected), + format::Substitute("Server responded with '{{message}}' ({{code}})", + {{"message", status_message(response)}, + {"code", format::str(status(response))}})); + } if (verbose_logging) { LOG(INFO) << "Server responded with " << body(response); } @@ -213,7 +226,8 @@ void SendMetadataRequest(std::vector&& entries, } void MetadataReporter::SendMetadata( - std::map&& metadata) { + std::map&& metadata) + throw (boost::system::system_error) { if (metadata.empty()) { if (agent_.config_.VerboseLogging()) { LOG(INFO) << "No data to send"; diff --git a/src/docker.cc b/src/docker.cc index c87d1698..33637888 100644 --- a/src/docker.cc +++ b/src/docker.cc @@ -21,6 +21,7 @@ #include #include +#include "format.h" #include "instance.h" #include "json.h" #include "logging.h" @@ -169,6 +170,13 @@ json::value DockerReader::QueryDocker(const std::string& path) const } try { http::local_client::response response = client.get(request); + if (status(response) != 200) { + throw boost::system::system_error( + boost::system::errc::make_error_code(boost::system::errc::not_connected), + format::Substitute("Server responded with '{{message}}' ({{code}})", + {{"message", status_message(response)}, + {"code", format::str(status(response))}})); + } #ifdef VERBOSE LOG(DEBUG) << "QueryDocker: Response: " << body(response); #endif diff --git a/src/environment.cc b/src/environment.cc index 87d0e346..bb51d446 100644 --- a/src/environment.cc +++ b/src/environment.cc @@ -19,6 +19,7 @@ #include #include +#include "format.h" #include "logging.h" namespace http = boost::network::http; @@ -85,7 +86,15 @@ std::string Environment::GetMetadataString(const std::string& path) const { request << boost::network::header("Metadata-Flavor", "Google"); try { http::client::response response = client.get(request); - return body(response); + if (status(response) == 200) { + return body(response); + } else { + throw boost::system::system_error( + boost::system::errc::make_error_code(boost::system::errc::not_connected), + format::Substitute("Server responded with '{{message}}' ({{code}})", + {{"message", status_message(response)}, + {"code", format::str(status(response))}})); + } } catch (const boost::system::system_error& e) { LOG(ERROR) << "Exception: " << e.what() << ": '" << kGceMetadataServerAddress << path << "'"; diff --git a/src/format.cc b/src/format.cc index d1c60a13..c4ea2af2 100644 --- a/src/format.cc +++ b/src/format.cc @@ -20,6 +20,19 @@ namespace format { +namespace { +template +std::string AsString(T v) { + std::ostringstream out; + out << v; + return out.str(); +} +} + +std::string str(int i) { return AsString(i); } +std::string str(double d) { return AsString(d); } +std::string str(bool b) { return AsString(b); } + std::string Substitute(const std::string& format, const std::map&& params) throw(Exception) { diff --git a/src/format.h b/src/format.h index 7129f388..0c07b89a 100644 --- a/src/format.h +++ b/src/format.h @@ -30,6 +30,10 @@ class Exception { std::string explanation_; }; +std::string str(int); +std::string str(double); +std::string str(bool); + // Format string substitution. // Placeholder format is '{{param}}'. // All instances of each placeholder will be substituted by the value of the diff --git a/src/kubernetes.cc b/src/kubernetes.cc index a79ef2c4..e53bcadf 100644 --- a/src/kubernetes.cc +++ b/src/kubernetes.cc @@ -26,6 +26,7 @@ #include #include +#include "format.h" #include "http_common.h" #include "instance.h" #include "json.h" @@ -549,6 +550,13 @@ json::value KubernetesReader::QueryMaster(const std::string& path) const } try { http::client::response response = client.get(request); + if (status(response) != 200) { + throw boost::system::system_error( + boost::system::errc::make_error_code(boost::system::errc::not_connected), + format::Substitute("Server responded with '{{message}}' ({{code}})", + {{"message", status_message(response)}, + {"code", format::str(status(response))}})); + } #ifdef VERBOSE LOG(DEBUG) << "QueryMaster: Response: " << body(response); #endif From 32e3db1dd2164224d3c605e90b5dfee0d4e63c4b Mon Sep 17 00:00:00 2001 From: Igor Peshansky Date: Sun, 25 Feb 2018 20:50:11 -0500 Subject: [PATCH 2/3] Handle HTTP response codes in the OAuth code. --- src/oauth2.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/oauth2.cc b/src/oauth2.cc index bcdcd4d4..7598c459 100644 --- a/src/oauth2.cc +++ b/src/oauth2.cc @@ -28,6 +28,7 @@ #include #include "base64.h" +#include "format.h" #include "http_common.h" #include "json.h" #include "logging.h" @@ -236,6 +237,13 @@ json::value OAuth2::ComputeTokenFromCredentials() const { << " body: " << request.body(); } http::client::response response = client.post(request); + if (status(response) != 200) { + throw boost::system::system_error( + boost::system::errc::make_error_code(boost::system::errc::not_connected), + format::Substitute("Server responded with '{{message}}' ({{code}})", + {{"message", status_message(response)}, + {"code", format::str(status(response))}})); + } if (environment_.config().VerboseLogging()) { LOG(INFO) << "Token response: " << body(response); } @@ -248,6 +256,9 @@ json::value OAuth2::ComputeTokenFromCredentials() const { } catch (const json::Exception& e) { LOG(ERROR) << e.what(); return nullptr; + } catch (const boost::system::system_error& e) { + LOG(ERROR) << "HTTP error: " << e.what(); + return nullptr; } } From b64acd4a377e180f0e26cb04bbace8127491de76 Mon Sep 17 00:00:00 2001 From: Igor Peshansky Date: Mon, 26 Feb 2018 01:11:22 -0500 Subject: [PATCH 3/3] Handle more codes; error tweaks. --- src/api_server.cc | 4 ++-- src/docker.cc | 2 +- src/environment.cc | 2 +- src/kubernetes.cc | 2 +- src/oauth2.cc | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/api_server.cc b/src/api_server.cc index c93cf9b4..fa14edc3 100644 --- a/src/api_server.cc +++ b/src/api_server.cc @@ -178,7 +178,7 @@ void MetadataReporter::ReportMetadata() { LOG(INFO) << "Metadata request sent successfully"; } } catch (const boost::system::system_error& e) { - LOG(ERROR) << "Unsuccessful: " << e.what(); + LOG(ERROR) << "Metadata request unsuccessful: " << e.what(); } std::this_thread::sleep_for(period_); } @@ -210,7 +210,7 @@ void SendMetadataRequest(std::vector&& entries, request << boost::network::header("Authorization", auth_header); request << boost::network::body(request_body); http::client::response response = client.post(request); - if (status(response) != 200) { + if (status(response) >= 300) { throw boost::system::system_error( boost::system::errc::make_error_code(boost::system::errc::not_connected), format::Substitute("Server responded with '{{message}}' ({{code}})", diff --git a/src/docker.cc b/src/docker.cc index 33637888..f9b8b7a4 100644 --- a/src/docker.cc +++ b/src/docker.cc @@ -170,7 +170,7 @@ json::value DockerReader::QueryDocker(const std::string& path) const } try { http::local_client::response response = client.get(request); - if (status(response) != 200) { + if (status(response) >= 300) { throw boost::system::system_error( boost::system::errc::make_error_code(boost::system::errc::not_connected), format::Substitute("Server responded with '{{message}}' ({{code}})", diff --git a/src/environment.cc b/src/environment.cc index bb51d446..6f3969e4 100644 --- a/src/environment.cc +++ b/src/environment.cc @@ -86,7 +86,7 @@ std::string Environment::GetMetadataString(const std::string& path) const { request << boost::network::header("Metadata-Flavor", "Google"); try { http::client::response response = client.get(request); - if (status(response) == 200) { + if (status(response) < 300) { return body(response); } else { throw boost::system::system_error( diff --git a/src/kubernetes.cc b/src/kubernetes.cc index e53bcadf..c4be0341 100644 --- a/src/kubernetes.cc +++ b/src/kubernetes.cc @@ -550,7 +550,7 @@ json::value KubernetesReader::QueryMaster(const std::string& path) const } try { http::client::response response = client.get(request); - if (status(response) != 200) { + if (status(response) >= 300) { throw boost::system::system_error( boost::system::errc::make_error_code(boost::system::errc::not_connected), format::Substitute("Server responded with '{{message}}' ({{code}})", diff --git a/src/oauth2.cc b/src/oauth2.cc index 7598c459..50ef1eab 100644 --- a/src/oauth2.cc +++ b/src/oauth2.cc @@ -237,7 +237,7 @@ json::value OAuth2::ComputeTokenFromCredentials() const { << " body: " << request.body(); } http::client::response response = client.post(request); - if (status(response) != 200) { + if (status(response) >= 300) { throw boost::system::system_error( boost::system::errc::make_error_code(boost::system::errc::not_connected), format::Substitute("Server responded with '{{message}}' ({{code}})",