Skip to content

Commit 0d364ae

Browse files
authored
YQ-2790 fixed uncaught exception in TS3FileWriteActor (#1242)
* Fixed uncaught exception in TS3FileWriteActor * Added try catch * Added AuthInfo initialization * Removed field AuthInfo * Fixed catch scope
1 parent 213bbe7 commit 0d364ae

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

ydb/library/yql/providers/s3/actors/yql_s3_write_actor.cpp

+35-7
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,16 @@ class TS3FileWriteActor : public TActorBootstrapped<TS3FileWriteActor> {
155155
void Bootstrap(const TActorId& parentId) {
156156
ParentId = parentId;
157157
LOG_D("TS3FileWriteActor", "Bootstrap by " << ParentId << " for Key: [" << Key << "], Url: [" << Url << "], request id: [" << RequestId << "]");
158-
auto authInfo = Credentials.GetAuthInfo();
158+
try {
159+
BeginPartsUpload(Credentials.GetAuthInfo());
160+
} catch (...) {
161+
FailOnException();
162+
}
163+
}
164+
165+
void BeginPartsUpload(const TS3Credentials::TAuthInfo& authInfo) {
159166
if (DirtyWrite && Parts->IsSealed() && Parts->Size() <= 1) {
160-
Become(&TS3FileWriteActor::SinglepartWorkingStateFunc);
167+
Become(&TS3FileWriteActor::StateFuncWrapper<&TS3FileWriteActor::SinglepartWorkingStateFunc>);
161168
const size_t size = Max<size_t>(Parts->Volume(), 1);
162169
InFlight += size;
163170
SentSize += size;
@@ -168,7 +175,7 @@ class TS3FileWriteActor : public TActorBootstrapped<TS3FileWriteActor> {
168175
true,
169176
RetryPolicy);
170177
} else {
171-
Become(&TS3FileWriteActor::MultipartInitialStateFunc);
178+
Become(&TS3FileWriteActor::StateFuncWrapper<&TS3FileWriteActor::MultipartInitialStateFunc>);
172179
Gateway->Upload(Url + "?uploads",
173180
IHTTPGateway::MakeYcHeaders(RequestId, authInfo.GetToken(), {}, authInfo.GetAwsUserPwd(), authInfo.GetAwsSigV4()),
174181
0,
@@ -186,7 +193,7 @@ class TS3FileWriteActor : public TActorBootstrapped<TS3FileWriteActor> {
186193

187194
void PassAway() override {
188195
if (InFlight || !Parts->Empty()) {
189-
AbortMultipartUpload();
196+
SafeAbortMultipartUpload();
190197
LOG_W("TS3FileWriteActor", "PassAway: but NOT finished, InFlight: " << InFlight << ", Parts: " << Parts->Size() << ", Sealed: " << Parts->IsSealed() << ", request id: [" << RequestId << "]");
191198
} else {
192199
LOG_D("TS3FileWriteActor", "PassAway: request id: [" << RequestId << "]");
@@ -236,6 +243,15 @@ class TS3FileWriteActor : public TActorBootstrapped<TS3FileWriteActor> {
236243
return InFlight + Parts->Volume();
237244
}
238245
private:
246+
template <void (TS3FileWriteActor::* DelegatedStateFunc)(STFUNC_SIG)>
247+
STFUNC(StateFuncWrapper) {
248+
try {
249+
(this->*DelegatedStateFunc)(ev);
250+
} catch (...) {
251+
FailOnException();
252+
}
253+
}
254+
239255
STRICT_STFUNC(MultipartInitialStateFunc,
240256
hFunc(TEvPrivate::TEvUploadStarted, Handle);
241257
)
@@ -347,7 +363,7 @@ class TS3FileWriteActor : public TActorBootstrapped<TS3FileWriteActor> {
347363

348364
void Handle(TEvPrivate::TEvUploadStarted::TPtr& result) {
349365
UploadId = result->Get()->UploadId;
350-
Become(&TS3FileWriteActor::MultipartWorkingStateFunc);
366+
Become(&TS3FileWriteActor::StateFuncWrapper<&TS3FileWriteActor::MultipartWorkingStateFunc>);
351367
StartUploadParts();
352368
}
353369

@@ -404,22 +420,34 @@ class TS3FileWriteActor : public TActorBootstrapped<TS3FileWriteActor> {
404420
RetryPolicy);
405421
}
406422

407-
void AbortMultipartUpload() {
423+
void SafeAbortMultipartUpload() {
424+
try {
425+
AbortMultipartUpload(Credentials.GetAuthInfo());
426+
} catch (...) {
427+
LOG_W("TS3FileWriteActor", "Failed to abort multipart upload, error: " << CurrentExceptionMessage());
428+
}
429+
}
430+
431+
void AbortMultipartUpload(const TS3Credentials::TAuthInfo& authInfo) {
408432
// Try to abort multipart upload in case of unexpected termination.
409433
// In case of error just logs warning.
410434

411435
if (!UploadId) {
412436
return;
413437
}
414438

415-
auto authInfo = Credentials.GetAuthInfo();
416439
Gateway->Delete(Url + "?uploadId=" + UploadId,
417440
IHTTPGateway::MakeYcHeaders(RequestId, authInfo.GetToken(), "application/xml", authInfo.GetAwsUserPwd(), authInfo.GetAwsSigV4()),
418441
std::bind(&TS3FileWriteActor::OnMultipartUploadAbort, ActorSystem, SelfId(), TxId, RequestId, std::placeholders::_1),
419442
RetryPolicy);
420443
UploadId.clear();
421444
}
422445

446+
void FailOnException() {
447+
Send(ParentId, new TEvPrivate::TEvUploadError(NYql::NDqProto::StatusIds::BAD_REQUEST, CurrentExceptionMessage()));
448+
SafeAbortMultipartUpload();
449+
}
450+
423451
size_t InFlight = 0ULL;
424452
size_t SentSize = 0ULL;
425453

ydb/tests/tools/kqprun/kqprun.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,19 @@ void RunMain(int argc, const char* argv[]) {
232232
RunScript(executionOptions, runnerOptions);
233233
}
234234

235+
void KqprunTerminateHandler() {
236+
NColorizer::TColors colors = NColorizer::AutoColors(Cerr);
237+
238+
Cerr << colors.Red() << "======= terminate() call stack ========" << colors.Default() << Endl;
239+
FormatBackTrace(&Cerr);
240+
Cerr << colors.Red() << "=======================================" << colors.Default() << Endl;
241+
242+
abort();
243+
}
235244

236245
int main(int argc, const char* argv[]) {
246+
std::set_terminate(KqprunTerminateHandler);
247+
237248
try {
238249
RunMain(argc, argv);
239250
} catch (...) {

0 commit comments

Comments
 (0)