error_code.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #pragma once
  2. #include <library/cpp/yt/misc/enum.h>
  3. #include <library/cpp/yt/misc/port.h>
  4. #include <library/cpp/yt/misc/static_initializer.h>
  5. #include <library/cpp/yt/string/format.h>
  6. #include <util/generic/hash_set.h>
  7. namespace NYT {
  8. ////////////////////////////////////////////////////////////////////////////////
  9. class TErrorCodeRegistry
  10. {
  11. public:
  12. static TErrorCodeRegistry* Get();
  13. struct TErrorCodeInfo
  14. {
  15. TString Namespace;
  16. //! Human-readable error code name.
  17. TString Name;
  18. bool operator==(const TErrorCodeInfo& rhs) const;
  19. };
  20. struct TErrorCodeRangeInfo
  21. {
  22. int From;
  23. int To;
  24. TString Namespace;
  25. std::function<TString(int code)> Formatter;
  26. TErrorCodeInfo Get(int code) const;
  27. bool Intersects(const TErrorCodeRangeInfo& other) const;
  28. bool Contains(int value) const;
  29. };
  30. //! Retrieves info from registered codes and code ranges.
  31. TErrorCodeInfo Get(int code) const;
  32. //! Retrieves information about registered codes.
  33. THashMap<int, TErrorCodeInfo> GetAllErrorCodes() const;
  34. //! Retrieves information about registered code ranges.
  35. std::vector<TErrorCodeRangeInfo> GetAllErrorCodeRanges() const;
  36. //! Registers a single error code.
  37. void RegisterErrorCode(int code, const TErrorCodeInfo& errorCodeInfo);
  38. //! Registers a range of error codes given a human-readable code to name formatter.
  39. void RegisterErrorCodeRange(int from, int to, TString namespaceName, std::function<TString(int code)> formatter);
  40. static TString ParseNamespace(const std::type_info& errorCodeEnumTypeInfo);
  41. private:
  42. THashMap<int, TErrorCodeInfo> CodeToInfo_;
  43. std::vector<TErrorCodeRangeInfo> ErrorCodeRanges_;
  44. void CheckCodesAgainstRanges() const;
  45. };
  46. void FormatValue(
  47. TStringBuilderBase* builder,
  48. const TErrorCodeRegistry::TErrorCodeInfo& errorCodeInfo,
  49. TStringBuf spec);
  50. void FormatValue(
  51. TStringBuilderBase* builder,
  52. const TErrorCodeRegistry::TErrorCodeRangeInfo& errorCodeInfo,
  53. TStringBuf spec);
  54. ////////////////////////////////////////////////////////////////////////////////
  55. #define YT_DEFINE_ERROR_ENUM(seq) \
  56. DEFINE_ENUM(EErrorCode, seq); \
  57. YT_ATTRIBUTE_USED inline const void* ErrorEnum_EErrorCode = [] { \
  58. for (auto errorCode : ::NYT::TEnumTraits<EErrorCode>::GetDomainValues()) { \
  59. ::NYT::TErrorCodeRegistry::Get()->RegisterErrorCode( \
  60. static_cast<int>(errorCode), \
  61. {::NYT::TErrorCodeRegistry::ParseNamespace(typeid(EErrorCode)), ToString(errorCode)}); \
  62. } \
  63. return nullptr; \
  64. } ()
  65. ////////////////////////////////////////////////////////////////////////////////
  66. //! NB: This macro should only by used in cpp files.
  67. #define YT_DEFINE_ERROR_CODE_RANGE(from, to, namespaceName, formatter) \
  68. YT_STATIC_INITIALIZER( \
  69. ::NYT::TErrorCodeRegistry::Get()->RegisterErrorCodeRange( \
  70. from, \
  71. to, \
  72. namespaceName, \
  73. formatter));
  74. ////////////////////////////////////////////////////////////////////////////////
  75. } // namespace NYT