diff --git a/ydb/library/yql/providers/s3/actors/yql_s3_write_actor.cpp b/ydb/library/yql/providers/s3/actors/yql_s3_write_actor.cpp index 6185dc1e0282..46bf335802c0 100644 --- a/ydb/library/yql/providers/s3/actors/yql_s3_write_actor.cpp +++ b/ydb/library/yql/providers/s3/actors/yql_s3_write_actor.cpp @@ -155,9 +155,16 @@ class TS3FileWriteActor : public TActorBootstrapped { void Bootstrap(const TActorId& parentId) { ParentId = parentId; LOG_D("TS3FileWriteActor", "Bootstrap by " << ParentId << " for Key: [" << Key << "], Url: [" << Url << "], request id: [" << RequestId << "]"); - auto authInfo = Credentials.GetAuthInfo(); + try { + BeginPartsUpload(Credentials.GetAuthInfo()); + } catch (...) { + FailOnException(); + } + } + + void BeginPartsUpload(const TS3Credentials::TAuthInfo& authInfo) { if (DirtyWrite && Parts->IsSealed() && Parts->Size() <= 1) { - Become(&TS3FileWriteActor::SinglepartWorkingStateFunc); + Become(&TS3FileWriteActor::StateFuncWrapper<&TS3FileWriteActor::SinglepartWorkingStateFunc>); const size_t size = Max(Parts->Volume(), 1); InFlight += size; SentSize += size; @@ -168,7 +175,7 @@ class TS3FileWriteActor : public TActorBootstrapped { true, RetryPolicy); } else { - Become(&TS3FileWriteActor::MultipartInitialStateFunc); + Become(&TS3FileWriteActor::StateFuncWrapper<&TS3FileWriteActor::MultipartInitialStateFunc>); Gateway->Upload(Url + "?uploads", IHTTPGateway::MakeYcHeaders(RequestId, authInfo.GetToken(), {}, authInfo.GetAwsUserPwd(), authInfo.GetAwsSigV4()), 0, @@ -186,7 +193,7 @@ class TS3FileWriteActor : public TActorBootstrapped { void PassAway() override { if (InFlight || !Parts->Empty()) { - AbortMultipartUpload(); + SafeAbortMultipartUpload(); LOG_W("TS3FileWriteActor", "PassAway: but NOT finished, InFlight: " << InFlight << ", Parts: " << Parts->Size() << ", Sealed: " << Parts->IsSealed() << ", request id: [" << RequestId << "]"); } else { LOG_D("TS3FileWriteActor", "PassAway: request id: [" << RequestId << "]"); @@ -236,6 +243,15 @@ class TS3FileWriteActor : public TActorBootstrapped { return InFlight + Parts->Volume(); } private: + template + STFUNC(StateFuncWrapper) { + try { + (this->*DelegatedStateFunc)(ev); + } catch (...) { + FailOnException(); + } + } + STRICT_STFUNC(MultipartInitialStateFunc, hFunc(TEvPrivate::TEvUploadStarted, Handle); ) @@ -347,7 +363,7 @@ class TS3FileWriteActor : public TActorBootstrapped { void Handle(TEvPrivate::TEvUploadStarted::TPtr& result) { UploadId = result->Get()->UploadId; - Become(&TS3FileWriteActor::MultipartWorkingStateFunc); + Become(&TS3FileWriteActor::StateFuncWrapper<&TS3FileWriteActor::MultipartWorkingStateFunc>); StartUploadParts(); } @@ -404,7 +420,15 @@ class TS3FileWriteActor : public TActorBootstrapped { RetryPolicy); } - void AbortMultipartUpload() { + void SafeAbortMultipartUpload() { + try { + AbortMultipartUpload(Credentials.GetAuthInfo()); + } catch (...) { + LOG_W("TS3FileWriteActor", "Failed to abort multipart upload, error: " << CurrentExceptionMessage()); + } + } + + void AbortMultipartUpload(const TS3Credentials::TAuthInfo& authInfo) { // Try to abort multipart upload in case of unexpected termination. // In case of error just logs warning. @@ -412,7 +436,6 @@ class TS3FileWriteActor : public TActorBootstrapped { return; } - auto authInfo = Credentials.GetAuthInfo(); Gateway->Delete(Url + "?uploadId=" + UploadId, IHTTPGateway::MakeYcHeaders(RequestId, authInfo.GetToken(), "application/xml", authInfo.GetAwsUserPwd(), authInfo.GetAwsSigV4()), std::bind(&TS3FileWriteActor::OnMultipartUploadAbort, ActorSystem, SelfId(), TxId, RequestId, std::placeholders::_1), @@ -420,6 +443,11 @@ class TS3FileWriteActor : public TActorBootstrapped { UploadId.clear(); } + void FailOnException() { + Send(ParentId, new TEvPrivate::TEvUploadError(NYql::NDqProto::StatusIds::BAD_REQUEST, CurrentExceptionMessage())); + SafeAbortMultipartUpload(); + } + size_t InFlight = 0ULL; size_t SentSize = 0ULL; diff --git a/ydb/tests/tools/kqprun/kqprun.cpp b/ydb/tests/tools/kqprun/kqprun.cpp index 7d91b3977e7f..5b250f2734da 100644 --- a/ydb/tests/tools/kqprun/kqprun.cpp +++ b/ydb/tests/tools/kqprun/kqprun.cpp @@ -232,8 +232,19 @@ void RunMain(int argc, const char* argv[]) { RunScript(executionOptions, runnerOptions); } +void KqprunTerminateHandler() { + NColorizer::TColors colors = NColorizer::AutoColors(Cerr); + + Cerr << colors.Red() << "======= terminate() call stack ========" << colors.Default() << Endl; + FormatBackTrace(&Cerr); + Cerr << colors.Red() << "=======================================" << colors.Default() << Endl; + + abort(); +} int main(int argc, const char* argv[]) { + std::set_terminate(KqprunTerminateHandler); + try { RunMain(argc, argv); } catch (...) {