diff --git a/fdbclient/S3BlobStore.actor.cpp b/fdbclient/S3BlobStore.actor.cpp index 73f704c6de0..7dc097f8248 100644 --- a/fdbclient/S3BlobStore.actor.cpp +++ b/fdbclient/S3BlobStore.actor.cpp @@ -846,6 +846,36 @@ std::string awsCanonicalURI(const std::string& resource, std::vector xmlBuffer(xmlResponse.begin(), xmlResponse.end()); + xmlBuffer.push_back('\0'); // Ensure null-terminated string + // Parse the XML + xml_document<> doc; + doc.parse<0>(&xmlBuffer[0]); + // Find the root node + xml_node<>* root = doc.first_node("Error"); + if (!root) { + TraceEvent(SevWarn, "ParseS3XMLResponseNoError").detail("Response", xmlResponse).log(); + return ""; + } + // Find the node + xml_node<>* codeNode = root->first_node("Code"); + if (!codeNode) { + TraceEvent(SevWarn, "ParseS3XMLResponseNoErrorCode").detail("Response", xmlResponse).log(); + return ""; + } + return std::string(codeNode->value()); + } catch (Error e) { + TraceEvent("BackupParseS3ErrorCodeFailure").errorUnsuppressed(e); + throw backup_parse_s3_response_failure(); + } catch (...) { + throw backup_parse_s3_response_failure(); + } +} + // Do a request, get a Response. // Request content is provided as UnsentPacketQueue *pContent which will be depleted as bytes are sent but the queue // itself must live for the life of this actor and be destroyed by the caller @@ -891,6 +921,7 @@ ACTOR Future> doRequest_impl(Referenceknobs.request_tries, bstore->knobs.connect_tries); state int thisTry = 1; + state int badRequestCode = 400; state double nextRetryDelay = 2.0; loop { @@ -1031,6 +1062,14 @@ ACTOR Future> doRequest_impl(Referencecode); + std::string s3Error = parseErrorCodeFromS3(r->data.content); + event.detail("S3ErrorCode", s3Error); + if (r->code == badRequestCode) { + TraceEvent(SevWarnAlways, "S3BlobStoreBadRequest") + .detail("HttpCode", r->code) + .detail("HttpResponseContent", r->data.content) + .detail("S3Error", s3Error); + } } event.detail("ConnectionEstablished", connectionEstablished); diff --git a/flow/include/flow/error_definitions.h b/flow/include/flow/error_definitions.h index c2089d13700..6963faae082 100755 --- a/flow/include/flow/error_definitions.h +++ b/flow/include/flow/error_definitions.h @@ -337,6 +337,7 @@ ERROR( backup_auth_unreadable, 2318, "Cannot read or parse one or more sources o ERROR( backup_does_not_exist, 2319, "Backup does not exist") ERROR( backup_not_filterable_with_key_ranges, 2320, "Backup before 6.3 cannot be filtered with key ranges") ERROR( backup_not_overlapped_with_keys_filter, 2321, "Backup key ranges doesn't overlap with key ranges filter") +ERROR( backup_parse_s3_response_failure, 2322, "cannot parse s3 response properly" ) ERROR( restore_invalid_version, 2361, "Invalid restore version") ERROR( restore_corrupted_data, 2362, "Corrupted backup data") ERROR( restore_missing_data, 2363, "Missing backup data")