error_attributes.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include "error_attributes.h"
  2. #include "error.h"
  3. #include "error_code.h"
  4. namespace NYT {
  5. ////////////////////////////////////////////////////////////////////////////////
  6. std::vector<TErrorAttributes::TKey> TErrorAttributes::ListKeys() const
  7. {
  8. std::vector<TKey> keys;
  9. keys.reserve(Map_.size());
  10. for (const auto& [key, value] : Map_) {
  11. keys.push_back(key);
  12. }
  13. return keys;
  14. }
  15. std::vector<TErrorAttributes::TKeyValuePair> TErrorAttributes::ListPairs() const
  16. {
  17. std::vector<TKeyValuePair> pairs;
  18. pairs.reserve(Map_.size());
  19. for (const auto& pair : Map_) {
  20. pairs.push_back(pair);
  21. }
  22. return pairs;
  23. }
  24. std::optional<TErrorAttribute::TValue> TErrorAttributes::FindValue(TStringBuf key) const
  25. {
  26. auto it = Map_.find(key);
  27. return it == Map_.end()
  28. ? std::nullopt
  29. : std::optional(it->second);
  30. }
  31. void TErrorAttributes::SetValue(const TKey& key, const TValue& value)
  32. {
  33. Map_[key] = value;
  34. }
  35. void TErrorAttributes::SetAttribute(const TErrorAttribute& attribute)
  36. {
  37. SetValue(attribute.Key, attribute.Value);
  38. }
  39. bool TErrorAttributes::Remove(const TKey& key)
  40. {
  41. return Map_.erase(key) > 0;
  42. }
  43. TErrorAttributes::TValue TErrorAttributes::GetValue(TStringBuf key) const
  44. {
  45. auto result = FindValue(key);
  46. if (!result) {
  47. ThrowNoSuchAttributeException(key);
  48. }
  49. return *result;
  50. }
  51. void TErrorAttributes::Clear()
  52. {
  53. Map_.clear();
  54. }
  55. bool TErrorAttributes::Contains(TStringBuf key) const
  56. {
  57. return Map_.contains(key);
  58. }
  59. bool operator == (const TErrorAttributes& lhs, const TErrorAttributes& rhs)
  60. {
  61. auto lhsPairs = lhs.ListPairs();
  62. auto rhsPairs = rhs.ListPairs();
  63. if (lhsPairs.size() != rhsPairs.size()) {
  64. return false;
  65. }
  66. std::sort(lhsPairs.begin(), lhsPairs.end(), [] (const auto& lhs, const auto& rhs) {
  67. return lhs.first < rhs.first;
  68. });
  69. std::sort(rhsPairs.begin(), rhsPairs.end(), [] (const auto& lhs, const auto& rhs) {
  70. return lhs.first < rhs.first;
  71. });
  72. for (auto index = 0; index < std::ssize(lhsPairs); ++index) {
  73. if (lhsPairs[index].first != rhsPairs[index].first) {
  74. return false;
  75. }
  76. }
  77. for (auto index = 0; index < std::ssize(lhsPairs); ++index) {
  78. if (lhsPairs[index].second != rhsPairs[index].second) {
  79. return false;
  80. }
  81. }
  82. return true;
  83. }
  84. ////////////////////////////////////////////////////////////////////////////////
  85. namespace {
  86. bool IsSpecialCharacter(char ch)
  87. {
  88. return ch == '\\' || ch == '/' || ch == '@' || ch == '*' || ch == '&' || ch == '[' || ch == '{';
  89. }
  90. // AppendYPathLiteral.
  91. void DoFormatAttributeKey(TStringBuilderBase* builder, TStringBuf value)
  92. {
  93. constexpr char asciiBegin = 32;
  94. constexpr char asciiEnd = 127;
  95. builder->Preallocate(value.length() + 16);
  96. for (unsigned char ch : value) {
  97. if (IsSpecialCharacter(ch)) {
  98. builder->AppendChar('\\');
  99. builder->AppendChar(ch);
  100. } else if (ch < asciiBegin || ch > asciiEnd) {
  101. builder->AppendString(TStringBuf("\\x"));
  102. builder->AppendChar(IntToHexLowercase[ch >> 4]);
  103. builder->AppendChar(IntToHexLowercase[ch & 0xf]);
  104. } else {
  105. builder->AppendChar(ch);
  106. }
  107. }
  108. }
  109. } // namespace
  110. ////////////////////////////////////////////////////////////////////////////////
  111. [[noreturn]] void TErrorAttributes::ThrowCannotParseAttributeException(TStringBuf key, const std::exception& ex)
  112. {
  113. THROW_ERROR_EXCEPTION(
  114. "Error parsing attribute %Qv",
  115. key)
  116. << ex;
  117. }
  118. [[noreturn]] void TErrorAttributes::ThrowNoSuchAttributeException(TStringBuf key)
  119. {
  120. auto formatAttributeKey = [] (auto key) {
  121. TStringBuilder builder;
  122. DoFormatAttributeKey(&builder, key);
  123. return builder.Flush();
  124. };
  125. THROW_ERROR_EXCEPTION(
  126. /*NYTree::EErrorCode::ResolveError*/ TErrorCode{500},
  127. "Attribute %Qv is not found",
  128. formatAttributeKey(key));
  129. }
  130. ////////////////////////////////////////////////////////////////////////////////
  131. } // namespace NYT