From 6c7f752c9857d53ab1b8392abd07892bcf4cac0e Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Wed, 11 Dec 2024 12:00:04 -0500 Subject: [PATCH 1/3] fixes --- .../include/aws/core/client/AWSErrorMarshaller.h | 3 +-- src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h b/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h index a486125f646..a406adec3bc 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h +++ b/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h @@ -91,11 +91,10 @@ namespace Aws protected: const Aws::Utils::Json::JsonValue& GetJsonPayloadFromError(const AWSError&) const; + AWSError MarshallHelper(const Aws::String& exceptionName, const Aws::String& message) const; }; class AWS_CORE_API JsonErrorMarshallerQueryCompatible : public JsonErrorMarshaller { - using AWSErrorMarshaller::Marshall; - public: /** * Converts an exceptionName and message into an Error object, if it diff --git a/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp b/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp index 418b2cf1e5a..0c2a403cd82 100644 --- a/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp +++ b/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp @@ -248,6 +248,9 @@ AWSError AWSErrorMarshaller::FindErrorByHttpResponseCode(Aws::Http:: { return CoreErrorsMapper::GetErrorForHttpResponseCode(code); } +AWSError JsonErrorMarshaller::MarshallHelper(const Aws::String& exceptionName, const Aws::String& message) const { + return AWSErrorMarshaller::Marshall(exceptionName, message); +} AWSError JsonErrorMarshallerQueryCompatible::Marshall(const Aws::Http::HttpResponse& httpResponse) const { Aws::StringStream memoryStream; @@ -266,9 +269,9 @@ AWSError JsonErrorMarshallerQueryCompatible::Marshall(const Aws::Htt : ""); if (httpResponse.HasHeader(ERROR_TYPE_HEADER)) { - error = AWSErrorMarshaller::Marshall(httpResponse.GetHeader(ERROR_TYPE_HEADER), message); + error = JsonErrorMarshaller::MarshallHelper(httpResponse.GetHeader(ERROR_TYPE_HEADER), message); } else if (payloadView.ValueExists(TYPE)) { - error = AWSErrorMarshaller::Marshall(payloadView.GetString(TYPE), message); + error = JsonErrorMarshaller::MarshallHelper(payloadView.GetString(TYPE), message); } else { error = FindErrorByHttpResponseCode(httpResponse.GetResponseCode()); error.SetMessage(message); From 4fb6f6bc975c3747953620595bf8863830201010 Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Wed, 11 Dec 2024 16:45:29 -0500 Subject: [PATCH 2/3] reuce duplicatation --- .../aws/core/client/AWSErrorMarshaller.h | 16 +++-- .../source/client/AWSErrorMarshaller.cpp | 60 +++++-------------- 2 files changed, 23 insertions(+), 53 deletions(-) diff --git a/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h b/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h index a406adec3bc..25f2c9aef14 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h +++ b/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h @@ -73,7 +73,9 @@ namespace Aws */ virtual Aws::String ExtractEndpoint(const AWSError&) const { return {}; } protected: - AWSError Marshall(const Aws::String& exceptionName, const Aws::String& message) const; + + virtual AWSError Marshall(const Aws::String& exceptionName, const Aws::String& message) const; + virtual void MarshallError(AWSError&, const Http::HttpResponse&) const {}; }; class AWS_CORE_API JsonErrorMarshaller : public AWSErrorMarshaller @@ -91,17 +93,13 @@ namespace Aws protected: const Aws::Utils::Json::JsonValue& GetJsonPayloadFromError(const AWSError&) const; - AWSError MarshallHelper(const Aws::String& exceptionName, const Aws::String& message) const; + static Aws::Utils::Json::JsonValue GetJsonPayloadHttpResponse(const Http::HttpResponse& httpResponse); + }; class AWS_CORE_API JsonErrorMarshallerQueryCompatible : public JsonErrorMarshaller { - public: - /** - * Converts an exceptionName and message into an Error object, if it - * can be parsed. Otherwise, it returns and AWSError with - * CoreErrors::UNKNOWN as the error type. - */ - AWSError Marshall(const Aws::Http::HttpResponse& response) const override; + protected: + void MarshallError(AWSError&, const Http::HttpResponse&) const override ; }; class AWS_CORE_API XmlErrorMarshaller : public AWSErrorMarshaller { diff --git a/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp b/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp index 0c2a403cd82..973c51b89e9 100644 --- a/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp +++ b/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp @@ -40,14 +40,19 @@ static CoreErrors GuessBodylessErrorType(const Aws::Http::HttpResponseCode respo } } -AWSError JsonErrorMarshaller::Marshall(const Aws::Http::HttpResponse& httpResponse) const { +JsonValue JsonErrorMarshaller::GetJsonPayloadHttpResponse(const Http::HttpResponse& httpResponse) +{ Aws::StringStream memoryStream; std::copy(std::istreambuf_iterator(httpResponse.GetResponseBody()), std::istreambuf_iterator(), std::ostreambuf_iterator(memoryStream)); Aws::String rawPayloadStr = memoryStream.str(); - JsonValue exceptionPayload(rawPayloadStr); - JsonView payloadView(exceptionPayload); + return JsonValue(rawPayloadStr); +} + +AWSError JsonErrorMarshaller::Marshall(const Aws::Http::HttpResponse& httpResponse) const { + auto exceptionPayload = GetJsonPayloadHttpResponse(httpResponse); + auto payloadView = JsonView(exceptionPayload); AWSError error; if (exceptionPayload.WasParseSuccessful()) { AWS_LOGSTREAM_TRACE(AWS_ERROR_MARSHALLER_LOG_TAG, "Error response is " << payloadView.WriteReadable()); @@ -68,10 +73,12 @@ AWSError JsonErrorMarshaller::Marshall(const Aws::Http::HttpResponse } else { bool isRetryable = IsRetryableHttpResponseCode(httpResponse.GetResponseCode()); AWS_LOGSTREAM_ERROR(AWS_ERROR_MARSHALLER_LOG_TAG, - "Failed to parse error payload: " << httpResponse.GetResponseCode() << ": " << rawPayloadStr); - error = AWSError(CoreErrors::UNKNOWN, "", "Failed to parse error payload: " + rawPayloadStr, isRetryable); + "Failed to parse error payload: " << httpResponse.GetResponseCode() << ": " << payloadView.AsString()); + error = AWSError(CoreErrors::UNKNOWN, "", "Failed to parse error payload: " + payloadView.AsString(), isRetryable); } + MarshallError(error, httpResponse); + error.SetRequestId(httpResponse.HasHeader(REQUEST_ID_HEADER) ? httpResponse.GetHeader(REQUEST_ID_HEADER) : ""); error.SetJsonPayload(std::move(exceptionPayload)); return error; @@ -248,36 +255,12 @@ AWSError AWSErrorMarshaller::FindErrorByHttpResponseCode(Aws::Http:: { return CoreErrorsMapper::GetErrorForHttpResponseCode(code); } -AWSError JsonErrorMarshaller::MarshallHelper(const Aws::String& exceptionName, const Aws::String& message) const { - return AWSErrorMarshaller::Marshall(exceptionName, message); -} - -AWSError JsonErrorMarshallerQueryCompatible::Marshall(const Aws::Http::HttpResponse& httpResponse) const { - Aws::StringStream memoryStream; - std::copy(std::istreambuf_iterator(httpResponse.GetResponseBody()), std::istreambuf_iterator(), - std::ostreambuf_iterator(memoryStream)); - Aws::String rawPayloadStr = memoryStream.str(); - - JsonValue exceptionPayload(rawPayloadStr); - JsonView payloadView(exceptionPayload); - AWSError error; - if (exceptionPayload.WasParseSuccessful()) { - AWS_LOGSTREAM_TRACE(AWS_ERROR_MARSHALLER_LOG_TAG, "Error response is " << payloadView.WriteReadable()); - - Aws::String message(payloadView.ValueExists(MESSAGE_CAMEL_CASE) ? payloadView.GetString(MESSAGE_CAMEL_CASE) - : payloadView.ValueExists(MESSAGE_LOWER_CASE) ? payloadView.GetString(MESSAGE_LOWER_CASE) - : ""); - - if (httpResponse.HasHeader(ERROR_TYPE_HEADER)) { - error = JsonErrorMarshaller::MarshallHelper(httpResponse.GetHeader(ERROR_TYPE_HEADER), message); - } else if (payloadView.ValueExists(TYPE)) { - error = JsonErrorMarshaller::MarshallHelper(payloadView.GetString(TYPE), message); - } else { - error = FindErrorByHttpResponseCode(httpResponse.GetResponseCode()); - error.SetMessage(message); - } +void JsonErrorMarshallerQueryCompatible::MarshallError(AWSError& error,const Http::HttpResponse& httpResponse) const +{ if (!error.GetExceptionName().empty()) { + auto exceptionPayload = GetJsonPayloadHttpResponse(httpResponse); + auto payloadView = JsonView(exceptionPayload); /* AWS Query-Compatible mode: This is a special setting that allows certain AWS services to communicate using a specific "query" @@ -316,15 +299,4 @@ AWSError JsonErrorMarshallerQueryCompatible::Marshall(const Aws::Htt } } } - - } else { - bool isRetryable = IsRetryableHttpResponseCode(httpResponse.GetResponseCode()); - AWS_LOGSTREAM_ERROR(AWS_ERROR_MARSHALLER_LOG_TAG, - "Failed to parse error payload: " << httpResponse.GetResponseCode() << ": " << rawPayloadStr); - error = AWSError(CoreErrors::UNKNOWN, "", "Failed to parse error payload: " + rawPayloadStr, isRetryable); - } - - error.SetRequestId(httpResponse.HasHeader(REQUEST_ID_HEADER) ? httpResponse.GetHeader(REQUEST_ID_HEADER) : ""); - error.SetJsonPayload(std::move(exceptionPayload)); - return error; } From 8e78bc69ed764ae6128bd6c260363d139e817ee7 Mon Sep 17 00:00:00 2001 From: Soumava Bera Date: Wed, 11 Dec 2024 16:46:34 -0500 Subject: [PATCH 3/3] refactored --- .../aws/core/client/AWSErrorMarshaller.h | 10 +-- .../source/client/AWSErrorMarshaller.cpp | 84 +++++++++---------- 2 files changed, 45 insertions(+), 49 deletions(-) diff --git a/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h b/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h index 25f2c9aef14..eda113ed3e9 100644 --- a/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h +++ b/src/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h @@ -73,9 +73,8 @@ namespace Aws */ virtual Aws::String ExtractEndpoint(const AWSError&) const { return {}; } protected: - - virtual AWSError Marshall(const Aws::String& exceptionName, const Aws::String& message) const; - virtual void MarshallError(AWSError&, const Http::HttpResponse&) const {}; + virtual AWSError Marshall(const Aws::String& exceptionName, const Aws::String& message) const; + virtual void MarshallError(AWSError&, const Http::HttpResponse&) const {}; }; class AWS_CORE_API JsonErrorMarshaller : public AWSErrorMarshaller @@ -94,12 +93,11 @@ namespace Aws protected: const Aws::Utils::Json::JsonValue& GetJsonPayloadFromError(const AWSError&) const; static Aws::Utils::Json::JsonValue GetJsonPayloadHttpResponse(const Http::HttpResponse& httpResponse); - }; class AWS_CORE_API JsonErrorMarshallerQueryCompatible : public JsonErrorMarshaller { - protected: - void MarshallError(AWSError&, const Http::HttpResponse&) const override ; + protected: + void MarshallError(AWSError&, const Http::HttpResponse&) const override; }; class AWS_CORE_API XmlErrorMarshaller : public AWSErrorMarshaller { diff --git a/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp b/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp index 973c51b89e9..53c1e7026d8 100644 --- a/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp +++ b/src/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp @@ -40,8 +40,7 @@ static CoreErrors GuessBodylessErrorType(const Aws::Http::HttpResponseCode respo } } -JsonValue JsonErrorMarshaller::GetJsonPayloadHttpResponse(const Http::HttpResponse& httpResponse) -{ +JsonValue JsonErrorMarshaller::GetJsonPayloadHttpResponse(const Http::HttpResponse& httpResponse) { Aws::StringStream memoryStream; std::copy(std::istreambuf_iterator(httpResponse.GetResponseBody()), std::istreambuf_iterator(), std::ostreambuf_iterator(memoryStream)); @@ -51,7 +50,7 @@ JsonValue JsonErrorMarshaller::GetJsonPayloadHttpResponse(const Http::HttpRespon } AWSError JsonErrorMarshaller::Marshall(const Aws::Http::HttpResponse& httpResponse) const { - auto exceptionPayload = GetJsonPayloadHttpResponse(httpResponse); + auto exceptionPayload = GetJsonPayloadHttpResponse(httpResponse); auto payloadView = JsonView(exceptionPayload); AWSError error; if (exceptionPayload.WasParseSuccessful()) { @@ -256,47 +255,46 @@ AWSError AWSErrorMarshaller::FindErrorByHttpResponseCode(Aws::Http:: return CoreErrorsMapper::GetErrorForHttpResponseCode(code); } -void JsonErrorMarshallerQueryCompatible::MarshallError(AWSError& error,const Http::HttpResponse& httpResponse) const -{ - if (!error.GetExceptionName().empty()) { - auto exceptionPayload = GetJsonPayloadHttpResponse(httpResponse); - auto payloadView = JsonView(exceptionPayload); - /* - AWS Query-Compatible mode: This is a special setting that allows - certain AWS services to communicate using a specific "query" - format, which can send customized error codes. Users are divided - into different groups based on how they communicate with the - service: Group #1: Users using the AWS Query format, receiving - custom error codes. Group #2: Users using the regular AWS JSON - format without the trait, receiving standard error codes. Group #3: - Users using the AWS JSON format with the trait, receiving custom - error codes. - - The header "x-amzn-query-error" shouldn't be present if it's not - awsQueryCompatible, so added checks for it. - */ - - if (httpResponse.HasHeader(QUERY_ERROR_HEADER)) { - auto errorCodeString = httpResponse.GetHeader(QUERY_ERROR_HEADER); - auto locationOfSemicolon = errorCodeString.find_first_of(';'); - Aws::String errorCode; - - if (locationOfSemicolon != Aws::String::npos) { - errorCode = errorCodeString.substr(0, locationOfSemicolon); - } else { - errorCode = errorCodeString; - } - - error.SetExceptionName(errorCode); +void JsonErrorMarshallerQueryCompatible::MarshallError(AWSError& error, const Http::HttpResponse& httpResponse) const { + if (!error.GetExceptionName().empty()) { + auto exceptionPayload = GetJsonPayloadHttpResponse(httpResponse); + auto payloadView = JsonView(exceptionPayload); + /* + AWS Query-Compatible mode: This is a special setting that allows + certain AWS services to communicate using a specific "query" + format, which can send customized error codes. Users are divided + into different groups based on how they communicate with the + service: Group #1: Users using the AWS Query format, receiving + custom error codes. Group #2: Users using the regular AWS JSON + format without the trait, receiving standard error codes. Group #3: + Users using the AWS JSON format with the trait, receiving custom + error codes. + + The header "x-amzn-query-error" shouldn't be present if it's not + awsQueryCompatible, so added checks for it. + */ + + if (httpResponse.HasHeader(QUERY_ERROR_HEADER)) { + auto errorCodeString = httpResponse.GetHeader(QUERY_ERROR_HEADER); + auto locationOfSemicolon = errorCodeString.find_first_of(';'); + Aws::String errorCode; + + if (locationOfSemicolon != Aws::String::npos) { + errorCode = errorCodeString.substr(0, locationOfSemicolon); + } else { + errorCode = errorCodeString; } - // check for exception name from payload field 'type' - else if (payloadView.ValueExists(TYPE)) { - // handle missing header and parse code from message - const auto& typeStr = payloadView.GetString(TYPE); - auto locationOfPound = typeStr.find_first_of('#'); - if (locationOfPound != Aws::String::npos) { - error.SetExceptionName(typeStr.substr(locationOfPound + 1)); - } + + error.SetExceptionName(errorCode); + } + // check for exception name from payload field 'type' + else if (payloadView.ValueExists(TYPE)) { + // handle missing header and parse code from message + const auto& typeStr = payloadView.GetString(TYPE); + auto locationOfPound = typeStr.find_first_of('#'); + if (locationOfPound != Aws::String::npos) { + error.SetExceptionName(typeStr.substr(locationOfPound + 1)); } } + } }