buffet: Added advanced error reporting

Created chromeos::Error class that encapsulates rich error
information from various system domains.

Swept GCD device registration, HTTP transport and utilities
to always return additional error information when the caller
requests it. This includes internal errors, general HTTP errors
as well as parsing and returning specific GCD and OAuth2 server
error responses.

Also fixed a number of existing linter warnings.

BUG=chromium:366709
TEST=All existing and new unit tests pass.

Change-Id: Ic01622a8efa3dc365ec106e595b09536818b9b23
Reviewed-on: https://chromium-review.googlesource.com/198772
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/http_utils.h b/buffet/http_utils.h
index c10805a..e44b378 100644
--- a/buffet/http_utils.h
+++ b/buffet/http_utils.h
@@ -5,8 +5,13 @@
 #ifndef BUFFET_HTTP_UTILS_H_
 #define BUFFET_HTTP_UTILS_H_
 
+#include "buffet/error.h"
 #include "buffet/http_request.h"
 
+#include <string>
+#include <utility>
+#include <vector>
+
 namespace base {
   class Value;
   class DictionaryValue;
@@ -15,6 +20,8 @@
 namespace chromeos {
 namespace http {
 
+extern const char kErrorDomainJSON[];
+
 typedef std::vector<std::pair<std::string, std::string>> FormFieldList;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -32,14 +39,17 @@
 std::unique_ptr<Response> SendRequest(
     const char* method, const std::string& url,
     const void* data, size_t data_size, const char* mime_type,
-    const HeaderList& headers, std::shared_ptr<Transport> transport);
+    const HeaderList& headers, std::shared_ptr<Transport> transport,
+    ErrorPtr* error);
 
 // Performs a simple GET request and returns the data as a string.
 std::string GetAsString(const std::string& url, const HeaderList& headers,
-                        std::shared_ptr<Transport> transport);
+                        std::shared_ptr<Transport> transport,
+                        ErrorPtr* error);
 inline std::string GetAsString(const std::string& url,
-                               std::shared_ptr<Transport> transport) {
-  return GetAsString(url, HeaderList(), transport);
+                               std::shared_ptr<Transport> transport,
+                               ErrorPtr* error) {
+  return GetAsString(url, HeaderList(), transport, error);
 }
 
 // Performs a GET request. Success status, returned data and additional
@@ -47,17 +57,20 @@
 // the returned Response object.
 std::unique_ptr<Response> Get(const std::string& url,
                               const HeaderList& headers,
-                              std::shared_ptr<Transport> transport);
+                              std::shared_ptr<Transport> transport,
+                              ErrorPtr* error);
 inline std::unique_ptr<Response> Get(
-    const std::string& url, std::shared_ptr<Transport> transport) {
-  return Get(url, HeaderList(), transport);
+    const std::string& url, std::shared_ptr<Transport> transport,
+    ErrorPtr* error) {
+  return Get(url, HeaderList(), transport, error);
 }
 
 // Performs a HEAD request. Success status and additional
 // information (such as returned HTTP headers) can be obtained from
 // the returned Response object.
 std::unique_ptr<Response> Head(const std::string& url,
-                               std::shared_ptr<Transport> transport);
+                               std::shared_ptr<Transport> transport,
+                               ErrorPtr* error);
 
 // Performs a POST request with binary data. Success status, returned data
 // and additional information (such as returned HTTP headers) can be obtained
@@ -68,18 +81,21 @@
                                      size_t data_size,
                                      const char* mime_type,
                                      const HeaderList& headers,
-                                     std::shared_ptr<Transport> transport);
+                                     std::shared_ptr<Transport> transport,
+                                     ErrorPtr* error);
 
 inline std::unique_ptr<Response> PostBinary(
     const std::string& url, const void* data, size_t data_size,
-    const char* mime_type, std::shared_ptr<Transport> transport) {
-  return PostBinary(url, data, data_size, mime_type, HeaderList(), transport);
+    const char* mime_type, std::shared_ptr<Transport> transport,
+    ErrorPtr* error) {
+  return PostBinary(url, data, data_size, mime_type, HeaderList(), transport,
+                    error);
 }
 
 inline std::unique_ptr<Response> PostBinary(
     const std::string& url, const void* data, size_t data_size,
-    std::shared_ptr<Transport> transport) {
-  return PostBinary(url, data, data_size, nullptr, transport);
+    std::shared_ptr<Transport> transport, ErrorPtr* error) {
+  return PostBinary(url, data, data_size, nullptr, transport, error);
 }
 
 // Performs a POST request with text data. Success status, returned data
@@ -91,18 +107,19 @@
                                    const char* data,
                                    const char* mime_type,
                                    const HeaderList& headers,
-                                   std::shared_ptr<Transport> transport);
+                                   std::shared_ptr<Transport> transport,
+                                   ErrorPtr* error);
 
 inline std::unique_ptr<Response> PostText(
     const std::string& url, const char* data, const char* mime_type,
-    std::shared_ptr<Transport> transport) {
-  return PostText(url, data, mime_type, HeaderList(), transport);
+    std::shared_ptr<Transport> transport, ErrorPtr* error) {
+  return PostText(url, data, mime_type, HeaderList(), transport, error);
 }
 
 inline std::unique_ptr<Response> PostText(
     const std::string& url, const char* data,
-    std::shared_ptr<Transport> transport) {
-  return PostText(url, data, nullptr, transport);
+    std::shared_ptr<Transport> transport, ErrorPtr* error) {
+  return PostText(url, data, nullptr, transport, error);
 }
 
 // Performs a POST request with form data. Success status, returned data
@@ -111,12 +128,13 @@
 // pairs. The data is posed as "application/x-www-form-urlencoded".
 std::unique_ptr<Response> PostFormData(
     const std::string& url, const FormFieldList& data,
-    const HeaderList& headers, std::shared_ptr<Transport> transport);
+    const HeaderList& headers, std::shared_ptr<Transport> transport,
+    ErrorPtr* error);
 
 inline std::unique_ptr<Response> PostFormData(
     const std::string& url, const FormFieldList& data,
-    std::shared_ptr<Transport> transport) {
-  return PostFormData(url, data, HeaderList(), transport);
+    std::shared_ptr<Transport> transport, ErrorPtr* error) {
+  return PostFormData(url, data, HeaderList(), transport, error);
 }
 
 // Performs a POST request with JSON data. Success status, returned data
@@ -126,12 +144,13 @@
 std::unique_ptr<Response> PostJson(const std::string& url,
                                    const base::Value* json,
                                    const HeaderList& headers,
-                                   std::shared_ptr<Transport> transport);
+                                   std::shared_ptr<Transport> transport,
+                                   ErrorPtr* error);
 
 inline std::unique_ptr<Response> PostJson(
     const std::string& url, const base::Value* json,
-    std::shared_ptr<Transport> transport) {
-  return PostJson(url, json, HeaderList(), transport);
+    std::shared_ptr<Transport> transport, ErrorPtr* error) {
+  return PostJson(url, json, HeaderList(), transport, error);
 }
 
 // Performs a PATCH request with JSON data. Success status, returned data
@@ -141,21 +160,22 @@
 std::unique_ptr<Response> PatchJson(const std::string& url,
                                     const base::Value* json,
                                     const HeaderList& headers,
-                                    std::shared_ptr<Transport> transport);
+                                    std::shared_ptr<Transport> transport,
+                                    ErrorPtr* error);
 
 inline std::unique_ptr<Response> PatchJson(
     const std::string& url, const base::Value* json,
-    std::shared_ptr<Transport> transport) {
-  return PatchJson(url, json, HeaderList(), transport);
+    std::shared_ptr<Transport> transport, ErrorPtr* error) {
+  return PatchJson(url, json, HeaderList(), transport, error);
 }
 
 // Given an http::Response object, parse the body data into Json object.
-// Returns null if failed. Optional |error_message| can be passed in to
+// Returns null if failed. Optional |error| can be passed in to
 // get the extended error information as to why the parse failed.
 std::unique_ptr<base::DictionaryValue> ParseJsonResponse(
-    const Response* response, int* status_code, std::string* error_message);
+    const Response* response, int* status_code, ErrorPtr* error);
 
-} // namespace http
-} // namespace chromeos
+}  // namespace http
+}  // namespace chromeos
 
-#endif // BUFFET_HTTP_UTILS_H_
+#endif  // BUFFET_HTTP_UTILS_H_