@@ -301,6 +301,110 @@ void JsonErrorMarshallerQueryCompatible::MarshallError(AWSError<CoreErrors>& err
301301 }
302302}
303303
304+ void RpcV2ErrorMarshallerQueryCompatible::MarshallError (AWSError<CoreErrors>& error, const Http::HttpResponse& httpResponse) const {
305+ if (!error.GetExceptionName ().empty ()) {
306+ /*
307+ AWS Query-Compatible mode: This is a special setting that allows
308+ certain AWS services to communicate using a specific "query"
309+ format, which can send customized error codes. Users are divided
310+ into different groups based on how they communicate with the
311+ service: Group #1: Users using the AWS Query format, receiving
312+ custom error codes. Group #2: Users using the regular AWS Cbor
313+ format without the trait, receiving standard error codes. Group #3:
314+ Users using the AWS Cbor format with the trait, receiving custom
315+ error codes.
316+
317+ The header "x-amzn-query-error" shouldn't be present if it's not
318+ awsQueryCompatible, so added checks for it.
319+ */
320+
321+ if (httpResponse.HasHeader (QUERY_ERROR_HEADER)) {
322+ auto errorCodeString = httpResponse.GetHeader (QUERY_ERROR_HEADER);
323+ auto locationOfSemicolon = errorCodeString.find_first_of (' ;' );
324+ Aws::String errorCode;
325+
326+ if (locationOfSemicolon != Aws::String::npos) {
327+ errorCode = errorCodeString.substr (0 , locationOfSemicolon);
328+ } else {
329+ errorCode = errorCodeString;
330+ }
331+
332+ error.SetExceptionName (errorCode);
333+ }
334+ // check for exception name from payload field 'type'
335+ else {
336+ // handle missing header and parse code from message
337+ auto exceptionPayload = GetCborPayloadHttpResponse (httpResponse);
338+ if (exceptionPayload.WasParseSuccessful ()) {
339+ auto decoder = exceptionPayload.GetDecoder ();
340+ Aws::String errorType;
341+ if (decoder != nullptr ) {
342+ auto initialMapType = decoder->PeekType ();
343+ if (initialMapType.has_value () && (initialMapType.value () == Aws::Crt::Cbor::CborType::MapStart ||
344+ initialMapType.value () == Aws::Crt::Cbor::CborType::IndefMapStart)) {
345+ if (initialMapType.value () == Aws::Crt::Cbor::CborType::MapStart) {
346+ auto mapSize = decoder->PopNextMapStart ();
347+ if (mapSize.has_value ()) {
348+ for (size_t i = 0 ; i < mapSize.value (); ++i) {
349+ auto key = decoder->PopNextTextVal ();
350+ if (key.has_value ()) {
351+ Aws::String keyStr (reinterpret_cast <const char *>(key.value ().ptr ), key.value ().len );
352+
353+ if (keyStr == TYPE) {
354+ auto val = decoder->PopNextTextVal ();
355+ if (val.has_value ()) {
356+ errorType = Aws::String (reinterpret_cast <const char *>(val.value ().ptr ), val.value ().len );
357+ }
358+ } else {
359+ decoder->ConsumeNextWholeDataItem ();
360+ }
361+ }
362+ if (decoder->LastError () != AWS_ERROR_UNKNOWN) {
363+ break ;
364+ }
365+ }
366+ }
367+ } else {
368+ decoder->ConsumeNextSingleElement ();
369+ while (decoder->LastError () == AWS_ERROR_UNKNOWN) {
370+ auto nextType = decoder->PeekType ();
371+ if (!nextType.has_value () || nextType.value () == Aws::Crt::Cbor::CborType::Break) {
372+ if (nextType.has_value ()) {
373+ decoder->ConsumeNextSingleElement ();
374+ }
375+ break ;
376+ }
377+
378+ auto key = decoder->PopNextTextVal ();
379+ if (key.has_value ()) {
380+ const Aws::String keyStr (reinterpret_cast <const char *>(key.value ().ptr ), key.value ().len );
381+
382+ if (keyStr == TYPE) {
383+ auto val = decoder->PopNextTextVal ();
384+ if (val.has_value ()) {
385+ errorType = Aws::String (reinterpret_cast <const char *>(val.value ().ptr ), val.value ().len );
386+ }
387+ } else {
388+ decoder->ConsumeNextWholeDataItem ();
389+ }
390+ }
391+ }
392+ }
393+ }
394+ }
395+
396+ if (errorType.empty ()) {
397+ return ;
398+ }
399+ auto locationOfPound = errorType.find_first_of (' #' );
400+ if (locationOfPound != Aws::String::npos) {
401+ error.SetExceptionName (errorType.substr (locationOfPound + 1 ));
402+ }
403+ }
404+ }
405+ }
406+ }
407+
304408CborValue RpcV2ErrorMarshaller::GetCborPayloadHttpResponse (const Http::HttpResponse& httpResponse) {
305409 return CborValue (httpResponse.GetResponseBody ());
306410}
0 commit comments