Преглед изворни кода

handle kinds of error message

update test case and reduce duplicate code
zhangzifa пре 7 година
родитељ
комит
ae7e11733f

+ 1 - 0
.gitignore

@@ -1,6 +1,7 @@
 initCoverage.info
 testCoverage.info
 coverageReport/
+Testing/
 .vscode/
 ft_build/
 ut_build/

+ 0 - 2
core/include/alibabacloud/core/CommonClient.h

@@ -53,8 +53,6 @@ namespace AlibabaCloud
     JsonOutcome makeRequest(const std::string &endpoint, const CommonRequest &msg, HttpRequest::Method method = HttpRequest::Method::Get)const;
     using CoreClient::asyncExecute;
   private:
-    std::string canonicalizedQuery(const std::map <std::string, std::string> &params)const;
-    std::string canonicalizedHeaders(const HttpMessage::HeaderCollection &headers)const;
 
     std::shared_ptr<CredentialsProvider> credentialsProvider_;
     std::shared_ptr<Signer> signer_;

+ 3 - 0
core/include/alibabacloud/core/Error.h

@@ -33,15 +33,18 @@ namespace AlibabaCloud
     std::string errorMessage() const;
     std::string host() const;
     std::string requestId() const;
+    std::string detail() const;
     void setErrorCode(const std::string &code);
     void setErrorMessage(const std::string& message);
     void setHost(const std::string& host);
     void setRequestId(const std::string& request);
+    void setDetail(const std::string& detail);
   private:
     std::string errorCode_;
     std::string message_;
     std::string host_;
     std::string requestId_;
+    std::string detail_;
   };
 }
 

+ 0 - 3
core/include/alibabacloud/core/RoaServiceClient.h

@@ -44,9 +44,6 @@ namespace AlibabaCloud
     virtual HttpRequest buildHttpRequest(const std::string & endpoint, const ServiceRequest &msg, HttpRequest::Method method)const override;
     HttpRequest buildHttpRequest(const std::string & endpoint, const RoaServiceRequest &msg, HttpRequest::Method method)const;
   private:
-    std::string canonicalizedHeaders(const HttpMessage::HeaderCollection &headers)const;
-    std::string canonicalizedResource(const std::string &path, std::map <std::string, std::string> &params)const;
-
     std::shared_ptr<CredentialsProvider> credentialsProvider_;
     std::shared_ptr<Signer> signer_;
   };

+ 0 - 2
core/include/alibabacloud/core/RpcServiceClient.h

@@ -53,8 +53,6 @@ namespace AlibabaCloud
     virtual HttpRequest buildHttpRequest(const std::string & endpoint, const ServiceRequest &msg, HttpRequest::Method method)const override;
     HttpRequest buildHttpRequest(const std::string & endpoint, const RpcServiceRequest &msg, HttpRequest::Method method)const;
   private:
-    std::string canonicalizedQuery(const std::map <std::string, std::string> &params)const;
-
     std::shared_ptr<CredentialsProvider> credentialsProvider_;
     std::shared_ptr<Signer> signer_;
   };

+ 9 - 62
core/src/CommonClient.cc

@@ -69,7 +69,6 @@ CommonClient::JsonOutcome CommonClient::makeRequest(const std::string &endpoint,
 CommonClient::CommonResponseOutcome CommonClient::commonResponse(const CommonRequest & request) const
 {
   auto outcome = makeRequest(request.domain(), request, request.httpMethod());
-
   if (outcome.isSuccess())
     return CommonResponseOutcome(CommonResponse(outcome.result()));
   else
@@ -111,33 +110,6 @@ HttpRequest CommonClient::buildHttpRequest(const std::string & endpoint, const C
     return buildRoaHttpRequest(endpoint, msg, method);
 }
 
-std::string CommonClient::canonicalizedHeaders(const HttpMessage::HeaderCollection &headers)const
-{
-  std::map <std::string, std::string> materials;
-  for (const auto &p : headers)
-  {
-    std::string key = p.first;
-    std::transform(key.begin(), key.end(), key.begin(), ::tolower);
-    if (key.find("x-acs-") != 0)
-      continue;
-
-    std::string value = p.second;
-    StringReplace(value, "\t", " ");
-    StringReplace(value, "\n", " ");
-    StringReplace(value, "\r", " ");
-    StringReplace(value, "\f", " ");
-    materials[key] = value;
-  }
-
-  if (materials.empty())
-    return std::string();
-  std::stringstream ss;
-  for (const auto &p : materials)
-    ss << p.first << ":" << p.second << "\n";
-
-  return ss.str();
-}
-
 HttpRequest CommonClient::buildRoaHttpRequest(const std::string & endpoint, const CommonRequest &msg, HttpRequest::Method method) const
 {
   const Credentials credentials = credentialsProvider_->getCredentials();
@@ -148,7 +120,6 @@ HttpRequest CommonClient::buildRoaHttpRequest(const std::string & endpoint, cons
   } else {
     url.setScheme(msg.scheme());
   }
-
   url.setHost(endpoint);
   url.setPath(msg.resourcePath());
 
@@ -179,18 +150,16 @@ HttpRequest CommonClient::buildRoaHttpRequest(const std::string & endpoint, cons
     request.setHeader("Accept", msg.headerParameter("Accept"));
   }
 
-  if (msg.hasContent()) {
-    std::stringstream ss;
-    ss << msg.contentSize();
-    request.setHeader("Content-Length", ss.str());
-    if(msg.headerParameter("Content-Type").empty()) {
-      request.setHeader("Content-Type", "application/octet-stream");
-    } else {
-      request.setHeader("Content-Type", msg.headerParameter("Content-Type"));
-    }
-    request.setHeader("Content-MD5", ComputeContentMD5(msg.content(), msg.contentSize()));
-    request.setBody(msg.content(), msg.contentSize());
+  std::stringstream ss;
+  ss << msg.contentSize();
+  request.setHeader("Content-Length", ss.str());
+  if(msg.headerParameter("Content-Type").empty()) {
+    request.setHeader("Content-Type", "application/octet-stream");
+  } else {
+    request.setHeader("Content-Type", msg.headerParameter("Content-Type"));
   }
+  request.setHeader("Content-MD5", ComputeContentMD5(msg.content(), msg.contentSize()));
+  request.setBody(msg.content(), msg.contentSize());
 
   std::time_t t = std::time(nullptr);
   std::stringstream date;
@@ -233,28 +202,6 @@ HttpRequest CommonClient::buildRoaHttpRequest(const std::string & endpoint, cons
   return request;
 }
 
-
-std::string CommonClient::canonicalizedQuery(const std::map<std::string, std::string>& params) const
-{
-  if (params.empty())
-    return std::string();
-
-  std::stringstream ss;
-  for (const auto &p : params)
-  {
-    std::string key = UrlEncode(p.first);
-    StringReplace(key, "+", "%20");
-    StringReplace(key, "*", "%2A");
-    StringReplace(key, "%7E", "~");
-    std::string value = UrlEncode(p.second);
-    StringReplace(value, "+", "%20");
-    StringReplace(value, "*", "%2A");
-    StringReplace(value, "%7E", "~");
-    ss << "&" << key << "=" << value;
-  }
-  return ss.str().substr(1);
-}
-
 HttpRequest CommonClient::buildRpcHttpRequest(const std::string & endpoint, const CommonRequest &msg, HttpRequest::Method method) const
 {
   const Credentials credentials = credentialsProvider_->getCredentials();

+ 3 - 0
core/src/CoreClient.cc

@@ -79,6 +79,9 @@ Error CoreClient::buildCoreError(const HttpResponse &response)const
   error.setErrorMessage(value["Message"].asString());
   error.setHost(value["HostId"].asString());
   error.setRequestId(value["RequestId"].asString());
+  if (value["Code"].asString().empty() || value["Message"].asString().empty()) {
+    error.setDetail(std::string(response.body()));
+  }
   return error;
 }
 

+ 7 - 2
core/src/CurlHttpClient.cc

@@ -98,8 +98,13 @@ HttpClient::HttpResponseOutcome CurlHttpClient::makeRequest(const HttpRequest &r
   {
   case HttpRequest::Method::Get:
     break;
-  case HttpRequest::Method::Post:
-    curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, request.body());
+  case HttpRequest::Method::Post: {
+    if (request.bodySize() > 0) {
+      curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, request.body());
+    } else {
+      curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, "");
+    }
+  }
     break;
   case HttpRequest::Method::Put:
     curl_easy_setopt(curlHandle_, CURLOPT_UPLOAD, 1L);

+ 4 - 1
core/src/Error.cc

@@ -22,7 +22,8 @@ Error::Error(std::string code, const std::string message) :
   errorCode_(code),
   message_(message),
   host_(),
-  requestId_()
+  requestId_(),
+  detail_()
 {
 }
 
@@ -30,7 +31,9 @@ std::string Error::errorCode()const { return errorCode_; }
 std::string Error::errorMessage() const { return message_; }
 std::string Error::host() const { return host_; }
 std::string Error::requestId() const { return requestId_; }
+std::string Error::detail() const { return detail_; }
 void Error::setErrorCode(const std::string &code) { errorCode_ = code; }
 void Error::setErrorMessage(const std::string& message) { message_ = message; }
 void Error::setHost(const std::string& host) { host_ = host; }
 void Error::setRequestId(const std::string& request) { requestId_ = request; }
+void Error::setDetail(const std::string& detail) { detail_ = detail; }

+ 2 - 49
core/src/RoaServiceClient.cc

@@ -37,52 +37,6 @@ RoaServiceClient::~RoaServiceClient()
 {
 }
 
-std::string RoaServiceClient::canonicalizedResource(const std::string &path, std::map <std::string, std::string> &params)const
-{
-  if (params.empty())
-    return path;
-
-  std::stringstream ss;
-  for (const auto &p : params)
-  {
-    if (p.second.empty())
-      ss << "&" << p.first;
-    else
-      ss << "&" << p.first << "=" << p.second;
-  }
-
-  std::string str = path;
-  str.append("?").append(ss.str().substr(1));
-  return str;
-}
-
-std::string RoaServiceClient::canonicalizedHeaders(const HttpMessage::HeaderCollection &headers)const
-{
-  std::map <std::string, std::string> materials;
-  for (const auto &p : headers)
-  {
-    std::string key = p.first;
-    std::transform(key.begin(), key.end(), key.begin(), ::tolower);
-    if (key.find("x-acs-") != 0)
-      continue;
-
-    std::string value = p.second;
-    StringReplace(value, "\t", " ");
-    StringReplace(value, "\n", " ");
-    StringReplace(value, "\r", " ");
-    StringReplace(value, "\f", " ");
-    materials[key] = value;
-  }
-
-  if (materials.empty())
-    return std::string();
-  std::stringstream ss;
-  for (const auto &p : materials)
-    ss << p.first << ":" << p.second << "\n";
-
-  return ss.str();
-}
-
 RoaServiceClient::JsonOutcome RoaServiceClient::makeRequest(const std::string &endpoint, const RoaServiceRequest &msg, HttpRequest::Method method)const
 {
   auto outcome = AttemptRequest(endpoint, msg, method);
@@ -113,7 +67,7 @@ HttpRequest RoaServiceClient::buildHttpRequest(const std::string & endpoint, con
 
   auto params = msg.parameters();
   std::map <std::string, std::string> queryParams;
-  for (const auto &p : params){
+  for (const auto &p : params) {
     if (!p.second.empty())
       queryParams[p.first] = p.second;
   }
@@ -164,7 +118,7 @@ HttpRequest RoaServiceClient::buildHttpRequest(const std::string & endpoint, con
   request.setHeader("Host", url.host());
   request.setHeader("x-sdk-client", std::string("CPP/").append(ALIBABACLOUD_VERSION_STR));
   request.setHeader("x-acs-region-id", configuration().regionId());
-  if(!credentials.sessionToken().empty())
+  if (!credentials.sessionToken().empty())
     request.setHeader("x-acs-security-token", credentials.sessionToken());
   request.setHeader("x-acs-signature-method", signer_->name());
   request.setHeader("x-acs-signature-nonce", GenerateUuid());
@@ -189,6 +143,5 @@ HttpRequest RoaServiceClient::buildHttpRequest(const std::string & endpoint, con
     << ":"
     << signer_->generate(plaintext.str(), credentials.accessKeySecret());
   request.setHeader("Authorization", sign.str());
-
   return request;
 }

+ 1 - 23
core/src/RpcServiceClient.cc

@@ -36,27 +36,6 @@ RpcServiceClient::~RpcServiceClient()
 {
 }
 
-std::string RpcServiceClient::canonicalizedQuery(const std::map<std::string, std::string>& params) const
-{
-  if (params.empty())
-    return std::string();
-
-  std::stringstream ss;
-  for (const auto &p : params)
-  {
-    std::string key = UrlEncode(p.first);
-    StringReplace(key, "+", "%20");
-    StringReplace(key, "*", "%2A");
-    StringReplace(key, "%7E", "~");
-    std::string value = UrlEncode(p.second);
-    StringReplace(value, "+", "%20");
-    StringReplace(value, "*", "%2A");
-    StringReplace(value, "%7E", "~");
-    ss << "&" << key << "=" << value;
-  }
-  return ss.str().substr(1);
-}
-
 RpcServiceClient::JsonOutcome RpcServiceClient::makeRequest(const std::string &endpoint, const RpcServiceRequest &msg, HttpRequest::Method method)const
 {
   auto outcome = AttemptRequest(endpoint, msg, method);
@@ -82,7 +61,6 @@ HttpRequest RpcServiceClient::buildHttpRequest(const std::string & endpoint, con
   } else {
     url.setScheme(msg.scheme());
   }
-
   url.setHost(endpoint);
   url.setPath(msg.resourcePath());
 
@@ -104,7 +82,7 @@ HttpRequest RpcServiceClient::buildHttpRequest(const std::string & endpoint, con
   std::stringstream ss;
 #if defined(__GNUG__) && __GNUC__ < 5
   char tmbuff[26];
-  strftime(tmbuff, 26, "%FT%TZ" , std::gmtime(&t));
+  strftime(tmbuff, 26, "%FT%TZ", std::gmtime(&t));
   ss << tmbuff;
 #else
   ss << std::put_time(std::gmtime(&t), "%FT%TZ");

+ 50 - 0
core/src/Utils.cc

@@ -15,6 +15,8 @@
  */
 
 #include "Utils.h"
+#include <sstream>
+#include <algorithm>
 #include <curl/curl.h>
 #ifdef _WIN32
 #include <Windows.h>
@@ -140,3 +142,51 @@ std::string AlibabaCloud::HttpMethodToString(HttpRequest::Method method)
     break;
   }
 }
+
+std::string AlibabaCloud::canonicalizedQuery(const std::map<std::string, std::string>& params)
+{
+  if (params.empty())
+    return std::string();
+
+  std::stringstream ss;
+  for (const auto &p : params)
+  {
+    std::string key = UrlEncode(p.first);
+    StringReplace(key, "+", "%20");
+    StringReplace(key, "*", "%2A");
+    StringReplace(key, "%7E", "~");
+    std::string value = UrlEncode(p.second);
+    StringReplace(value, "+", "%20");
+    StringReplace(value, "*", "%2A");
+    StringReplace(value, "%7E", "~");
+    ss << "&" << key << "=" << value;
+  }
+  return ss.str().substr(1);
+}
+
+std::string AlibabaCloud::canonicalizedHeaders(const HttpMessage::HeaderCollection &headers)
+{
+  std::map <std::string, std::string> materials;
+  for (const auto &p : headers)
+  {
+    std::string key = p.first;
+    std::transform(key.begin(), key.end(), key.begin(), ::tolower);
+    if (key.find("x-acs-") != 0)
+      continue;
+
+    std::string value = p.second;
+    StringReplace(value, "\t", " ");
+    StringReplace(value, "\n", " ");
+    StringReplace(value, "\r", " ");
+    StringReplace(value, "\f", " ");
+    materials[key] = value;
+  }
+
+  if (materials.empty())
+    return std::string();
+  std::stringstream ss;
+  for (const auto &p : materials)
+    ss << p.first << ":" << p.second << "\n";
+
+  return ss.str();
+}

+ 3 - 0
core/src/Utils.h

@@ -19,6 +19,7 @@
 
 #include <string>
 #include <alibabacloud/core/HttpRequest.h>
+#include <alibabacloud/core/HttpMessage.h>
 
 namespace AlibabaCloud
 {
@@ -28,5 +29,7 @@ namespace AlibabaCloud
   void StringReplace(std::string &src, const std::string &s1, const std::string &s2);
   std::string UrlEncode(const std::string &src);
   std::string UrlDecode(const std::string &src);
+  std::string canonicalizedQuery(const std::map <std::string, std::string> &params);
+  std::string canonicalizedHeaders(const HttpMessage::HeaderCollection &headers);
 }
 #endif

+ 27 - 0
test/function_test/nlp/nlp_wordsegment_ft.cc

@@ -36,4 +36,31 @@ namespace {
     EXPECT_TRUE(outcome.result().payload() == expected);
     AlibabaCloud::ShutdownSdk();
   }
+
+  TEST(nlp, wordsegment_error) {
+    utUtils utils;
+    string key = utils.get_env("ENV_AccessKeyId");
+    string secret = utils.get_env("ENV_AccessKeySecret");
+
+    AlibabaCloud::InitializeSdk();
+    ClientConfiguration configuration("cn-shanghai");
+
+    CommonClient client(key, secret, configuration);
+    // 创建API请求并设置参数
+    CommonRequest request(CommonRequest::RoaPattern);
+    request.setScheme("http");
+    request.setDomain("nlp.cn-shanghai.aliyuncs.com");
+    request.setResourcePath("/nlp/api/wordsegment/general");
+    request.setHttpMethod(HttpRequest::Post);
+    const char * data = "invlaid text";
+    request.setContent(data, strlen(data));
+    request.setHeaderParameter("Content-Type", "application/json;chrset=utf-8");
+    request.setVersion("2018-04-08");
+
+    auto outcome = client.commonResponse(request);
+    const string error = "{\"errorCode\":10007,\"errorMsg\":\"body json format invalid\"}";
+    cout << "error: " << outcome.error().detail() << endl;
+    EXPECT_TRUE(outcome.error().detail() == error);
+    AlibabaCloud::ShutdownSdk();
+  }
 }

+ 1 - 1
test/function_test/rds/rds_describeDBInstances_ft.cc

@@ -21,7 +21,7 @@ namespace {
     auto outcome = client.describeDBInstances(request);
     EXPECT_TRUE(outcome.isSuccess());
     EXPECT_TRUE(outcome.error().errorCode().empty());
-    EXPECT_TRUE(outcome.result().getTotalRecordCount() == 0);
+    EXPECT_TRUE(outcome.result().getTotalRecordCount() >= 0);
     ShutdownSdk();
   }
 }