diff --git a/ydb/library/yql/providers/s3/actors/yql_s3_applicator_actor.cpp b/ydb/library/yql/providers/s3/actors/yql_s3_applicator_actor.cpp index 5b8f95449f98..35d379bcab09 100644 --- a/ydb/library/yql/providers/s3/actors/yql_s3_applicator_actor.cpp +++ b/ydb/library/yql/providers/s3/actors/yql_s3_applicator_actor.cpp @@ -488,32 +488,38 @@ class TS3ApplicatorActor : public NActors::TActorBootstrappedGet()->Result; - if (!result.Issues && result.Content.HttpResponseCode >= 200 && result.Content.HttpResponseCode < 300) { - TS3Result s3Result(result.Content.Extract()); - if (s3Result.IsError) { - Finish(true, s3Result.S3ErrorCode + ": " + s3Result.ErrorMessage); - } else { - LOG_D("ListParts SUCCESS " << ev->Get()->State->BuildUrl()); - const auto& root = s3Result.GetRootNode(); - if (root.Name() == "ListPartsResult") { - const NXml::TNamespacesForXPath nss(1U, {"s3", "http://s3.amazonaws.com/doc/2006-03-01/"}); - auto state = ev->Get()->State->CompleteState; - state->Tags.reserve(state->Tags.size() + root.Node("s3:MaxParts", false, nss).Value()); - const auto& parts = root.XPath("s3:Part", true, nss); - for (const auto& part : parts) { - state->Tags.push_back(part.Node("s3:ETag", false, nss).Value()); - } - if (root.Node("s3:IsTruncated", false, nss).Value()) { - ev->Get()->State->PartNumberMarker = root.Node("s3:NextPartNumberMarker", false, nss).Value(); - PushListParts(ev->Get()->State); + if (!result.Issues) { + if (result.Content.HttpResponseCode == 404) { + LOG_W("ListParts NOT FOUND " << ev->Get()->State->BuildUrl() << " (multipart upload may be completed already)"); + return; + } + if (result.Content.HttpResponseCode >= 200 && result.Content.HttpResponseCode < 300) { + TS3Result s3Result(result.Content.Extract()); + if (s3Result.IsError) { + Finish(true, s3Result.S3ErrorCode + ": " + s3Result.ErrorMessage); + } else { + LOG_D("ListParts SUCCESS " << ev->Get()->State->BuildUrl()); + const auto& root = s3Result.GetRootNode(); + if (root.Name() == "ListPartsResult") { + const NXml::TNamespacesForXPath nss(1U, {"s3", "http://s3.amazonaws.com/doc/2006-03-01/"}); + auto state = ev->Get()->State->CompleteState; + state->Tags.reserve(state->Tags.size() + root.Node("s3:MaxParts", false, nss).Value()); + const auto& parts = root.XPath("s3:Part", true, nss); + for (const auto& part : parts) { + state->Tags.push_back(part.Node("s3:ETag", false, nss).Value()); + } + if (root.Node("s3:IsTruncated", false, nss).Value()) { + ev->Get()->State->PartNumberMarker = root.Node("s3:NextPartNumberMarker", false, nss).Value(); + PushListParts(ev->Get()->State); + } else { + PushCommitMultipartUpload(state); + } } else { - PushCommitMultipartUpload(state); + Finish(true, "ListParts reply: " + root.Name()); } - } else { - Finish(true, "ListParts reply: " + root.Name()); } + return; } - return; } const TString& url = ev->Get()->State->BuildUrl(); LOG_D("ListParts ERROR " << url);