aboutsummaryrefslogtreecommitdiffstats
path: root/yt
diff options
context:
space:
mode:
Diffstat (limited to 'yt')
-rw-r--r--yt/yt/core/misc/error.cpp74
-rw-r--r--yt/yt/core/misc/error.h3
-rw-r--r--yt/yt/core/misc/unittests/error_ut.cpp61
3 files changed, 126 insertions, 12 deletions
diff --git a/yt/yt/core/misc/error.cpp b/yt/yt/core/misc/error.cpp
index 4b16e27591..dad759be23 100644
--- a/yt/yt/core/misc/error.cpp
+++ b/yt/yt/core/misc/error.cpp
@@ -140,6 +140,11 @@ public:
Message_ = std::move(message);
}
+ TString* MutableMessage()
+ {
+ return &Message_;
+ }
+
bool HasOriginAttributes() const
{
return Host_.operator bool();
@@ -599,10 +604,10 @@ TError TError::Sanitize() const
return TError(std::move(result));
}
-TError TError::Truncate(int maxInnerErrorCount, i64 stringLimit) const
-{
- static const TString InnerErrorsTruncatedKey("inner_errors_truncated");
+const TString InnerErrorsTruncatedKey("inner_errors_truncated");
+TError TError::Truncate(int maxInnerErrorCount, i64 stringLimit) const &
+{
if (!Impl_) {
return TError();
}
@@ -619,16 +624,20 @@ TError TError::Truncate(int maxInnerErrorCount, i64 stringLimit) const
};
auto truncateAttributes = [stringLimit] (const IAttributeDictionary& attributes) {
- auto clonedAttributes = attributes.Clone();
- for (const auto& key : clonedAttributes->ListKeys()) {
- if (std::ssize(clonedAttributes->FindYson(key).AsStringBuf()) > stringLimit) {
- clonedAttributes->SetYson(
+ auto truncatedAttributes = CreateEphemeralAttributes();
+ for (const auto& key : attributes.ListKeys()) {
+ if (const auto& value = attributes.FindYson(key); std::ssize(value.AsStringBuf()) > stringLimit) {
+ truncatedAttributes->SetYson(
key,
BuildYsonStringFluently()
.Value("...<attribute truncated>..."));
+ } else {
+ truncatedAttributes->SetYson(
+ key,
+ value);
}
}
- return clonedAttributes;
+ return truncatedAttributes;
};
auto result = std::make_unique<TImpl>();
@@ -654,6 +663,55 @@ TError TError::Truncate(int maxInnerErrorCount, i64 stringLimit) const
return TError(std::move(result));
}
+TError TError::Truncate(int maxInnerErrorCount, i64 stringLimit) &&
+{
+ if (!Impl_) {
+ return TError();
+ }
+
+ auto truncateInnerError = [=] (TError& innerError) {
+ innerError = std::move(innerError).Truncate(maxInnerErrorCount, stringLimit);
+ };
+
+ auto truncateString = [stringLimit] (TString* string) {
+ if (std::ssize(*string) > stringLimit) {
+ *string = Format("%v...<message truncated>", string->substr(0, stringLimit));
+ }
+ };
+
+ auto truncateAttributes = [stringLimit] (IAttributeDictionary* attributes) {
+ for (const auto& key : attributes->ListKeys()) {
+ if (std::ssize(attributes->FindYson(key).AsStringBuf()) > stringLimit) {
+ attributes->SetYson(
+ key,
+ BuildYsonStringFluently()
+ .Value("...<attribute truncated>..."));
+ }
+ }
+ };
+
+ truncateString(Impl_->MutableMessage());
+ if (Impl_->HasAttributes()) {
+ truncateAttributes(Impl_->MutableAttributes());
+ }
+ if (std::ssize(InnerErrors()) <= maxInnerErrorCount) {
+ for (auto& innerError : *MutableInnerErrors()) {
+ truncateInnerError(innerError);
+ }
+ } else {
+ auto& innerErrors = *MutableInnerErrors();
+ MutableAttributes()->Set(InnerErrorsTruncatedKey, true);
+ for (int i = 0; i + 1 < maxInnerErrorCount; ++i) {
+ truncateInnerError(innerErrors[i]);
+ }
+ truncateInnerError(innerErrors.back());
+ innerErrors[maxInnerErrorCount - 1] = std::move(innerErrors.back());
+ innerErrors.resize(maxInnerErrorCount);
+ }
+
+ return std::move(*this);
+}
+
bool TError::IsOK() const
{
if (!Impl_) {
diff --git a/yt/yt/core/misc/error.h b/yt/yt/core/misc/error.h
index cdac4ab81e..b4edbf50f4 100644
--- a/yt/yt/core/misc/error.h
+++ b/yt/yt/core/misc/error.h
@@ -144,7 +144,8 @@ public:
// TODO(gritukan): This method is used only outside of YT. Remove it.
TError Sanitize() const;
- TError Truncate(int maxInnerErrorCount = 2, i64 stringLimit = 16_KB) const;
+ TError Truncate(int maxInnerErrorCount = 2, i64 stringLimit = 16_KB) const &;
+ TError Truncate(int maxInnerErrorCount = 2, i64 stringLimit = 16_KB) &&;
bool IsOK() const;
diff --git a/yt/yt/core/misc/unittests/error_ut.cpp b/yt/yt/core/misc/unittests/error_ut.cpp
index 53bd4d434c..22997c5118 100644
--- a/yt/yt/core/misc/unittests/error_ut.cpp
+++ b/yt/yt/core/misc/unittests/error_ut.cpp
@@ -70,7 +70,8 @@ TEST(TErrorTest, FormatCtor)
TEST(TErrorTest, TruncateSimple)
{
auto error = TError("Some error")
- << TErrorAttribute("my_attr", "Attr value");
+ << TErrorAttribute("my_attr", "Attr value")
+ << TError("Inner error");
auto truncatedError = error.Truncate();
EXPECT_EQ(error.GetCode(), truncatedError.GetCode());
EXPECT_EQ(error.GetMessage(), truncatedError.GetMessage());
@@ -79,17 +80,71 @@ TEST(TErrorTest, TruncateSimple)
EXPECT_EQ(error.GetSpanId(), truncatedError.GetSpanId());
EXPECT_EQ(error.GetDatetime(), truncatedError.GetDatetime());
EXPECT_EQ(error.Attributes().Get<TString>("my_attr"), truncatedError.Attributes().Get<TString>("my_attr"));
+ EXPECT_EQ(error.InnerErrors().size(), truncatedError.InnerErrors().size());
+ EXPECT_EQ(error.InnerErrors()[0].GetMessage(), truncatedError.InnerErrors()[0].GetMessage());
}
TEST(TErrorTest, TruncateLarge)
{
- auto error = TError("Some long long error");
+ auto error = TError("Some long long error")
+ << TError("First inner error")
+ << TError("Second inner error")
+ << TError("Third inner error")
+ << TError("Fourth inner error");
error.MutableAttributes()->Set("my_attr", "Some long long attr");
- auto truncatedError = error.Truncate(/*maxInnerErrorCount*/ 2, /*stringLimit*/ 10);
+ auto truncatedError = error.Truncate(/*maxInnerErrorCount*/ 3, /*stringLimit*/ 10);
EXPECT_EQ(error.GetCode(), truncatedError.GetCode());
EXPECT_EQ("Some long ...<message truncated>", truncatedError.GetMessage());
EXPECT_EQ("...<attribute truncated>...", truncatedError.Attributes().Get<TString>("my_attr"));
+ EXPECT_EQ(truncatedError.InnerErrors().size(), 3u);
+
+ EXPECT_EQ("First inne...<message truncated>", truncatedError.InnerErrors()[0].GetMessage());
+ EXPECT_EQ("Second inn...<message truncated>", truncatedError.InnerErrors()[1].GetMessage());
+ EXPECT_EQ("Fourth inn...<message truncated>", truncatedError.InnerErrors()[2].GetMessage());
+}
+
+TEST(TErrorTest, TruncateSimpleRValue)
+{
+ auto error = TError("Some error")
+ << TErrorAttribute("my_attr", "Attr value")
+ << TError("Inner error");
+ auto errorCopy = error;
+ auto truncatedError = std::move(errorCopy).Truncate();
+ EXPECT_EQ(NYT::EErrorCode::OK, errorCopy.GetCode());
+
+ EXPECT_EQ(error.GetCode(), truncatedError.GetCode());
+ EXPECT_EQ(error.GetMessage(), truncatedError.GetMessage());
+ EXPECT_EQ(error.GetPid(), truncatedError.GetPid());
+ EXPECT_EQ(error.GetTid(), truncatedError.GetTid());
+ EXPECT_EQ(error.GetSpanId(), truncatedError.GetSpanId());
+ EXPECT_EQ(error.GetDatetime(), truncatedError.GetDatetime());
+ EXPECT_EQ(error.Attributes().Get<TString>("my_attr"), truncatedError.Attributes().Get<TString>("my_attr"));
+ EXPECT_EQ(error.InnerErrors().size(), truncatedError.InnerErrors().size());
+ EXPECT_EQ(error.InnerErrors()[0].GetMessage(), truncatedError.InnerErrors()[0].GetMessage());
+}
+
+TEST(TErrorTest, TruncateLargeRValue)
+{
+ auto error = TError("Some long long error")
+ << TError("First inner error")
+ << TError("Second inner error")
+ << TError("Third inner error")
+ << TError("Fourth inner error");
+ error.MutableAttributes()->Set("my_attr", "Some long long attr");
+
+ auto errorCopy = error;
+ auto truncatedError = std::move(errorCopy).Truncate(/*maxInnerErrorCount*/ 3, /*stringLimit*/ 10);
+ EXPECT_EQ(NYT::EErrorCode::OK, errorCopy.GetCode());
+
+ EXPECT_EQ(error.GetCode(), truncatedError.GetCode());
+ EXPECT_EQ("Some long ...<message truncated>", truncatedError.GetMessage());
+ EXPECT_EQ("...<attribute truncated>...", truncatedError.Attributes().Get<TString>("my_attr"));
+ EXPECT_EQ(truncatedError.InnerErrors().size(), 3u);
+
+ EXPECT_EQ("First inne...<message truncated>", truncatedError.InnerErrors()[0].GetMessage());
+ EXPECT_EQ("Second inn...<message truncated>", truncatedError.InnerErrors()[1].GetMessage());
+ EXPECT_EQ("Fourth inn...<message truncated>", truncatedError.InnerErrors()[2].GetMessage());
}
TEST(TErrorTest, YTExceptionToError)