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