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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
{
"format": 1,
"id": "saw-error",
"kind": "class",
"name": "error",
"namespace": "saw",
"module": "core",
"header": "modules/core/c++/error.hpp",
"brief_description": "Exception replacement. Carries a code, a criticality and a message.",
"detailed_description": [
[
"The library is written without exceptions, so this takes their place. An error is either recoverable or critical, and the code distinguishes the kind. Additional kinds are added by defining a tag struct with a description and an is_critical flag, which registers itself the first time it is used."
],
[
"The code is an index into a process local registry handed out in first use order. Only",
{"name": "no_error", "id": "saw-err-no_error"},
{"name": "not_found", "id": "saw-err-not_found"},
"and",
{"name": "out_of_memory", "id": "saw-err-out_of_memory"},
"are preregistered, so the same error has different codes in two processes. A code must therefore never be sent anywhere; the category string is the portable identity."
],
[
"Copying is forbidden on purpose. An error is moved, or copied explicitly through copy_error, so passing one around stays visible at the call site."
]
],
"attributes": {
"saw-error-error_code_": {
"id": "saw-error-error_code_",
"name": "error_code_",
"type": ["code"],
"visibility": "private",
"brief_description": "Distinguishes the different error types."
},
"saw-error-is_critical_": {
"id": "saw-error-is_critical_",
"name": "is_critical_",
"type": ["bool"],
"visibility": "private",
"brief_description": "Kept next to the code so checking doesn't need the registry."
},
"saw-error-error_message_": {
"id": "saw-error-error_message_",
"name": "error_message_",
"type": ["std::variant< std::string_view, std::string >"],
"visibility": "private",
"brief_description": "A variant for the edge case of being out of memory, where a string cannot be built."
}
},
"aliases": {
"saw-error-code": {
"id": "saw-error-code",
"name": "code",
"type": ["uint32_t"],
"brief_description": "Type representing the error code."
}
},
"functions": {
"saw-error-ctor-1": {
"id": "saw-error-ctor-1",
"name": "error",
"type": [],
"parameters": [
{"name": "id", "type": ["error::code"]},
{"name": "is_critical", "type": ["bool"]}
]
},
"saw-error-ctor-2": {
"id": "saw-error-ctor-2",
"name": "error",
"type": [],
"brief_description": "With a message which outlives the error, such as a literal.",
"parameters": [
{"name": "id", "type": ["error::code"]},
{"name": "is_critical", "type": ["bool"]},
{"name": "msg", "type": ["const std::string_view &"]}
]
},
"saw-error-ctor-3": {
"id": "saw-error-ctor-3",
"name": "error",
"type": [],
"brief_description": "With an owned message, for text built at the point of failure.",
"parameters": [
{"name": "id", "type": ["error::code"]},
{"name": "is_critical", "type": ["bool"]},
{"name": "msg", "type": ["std::string &&"]}
]
},
"saw-error-get_message": {
"id": "saw-error-get_message",
"name": "get_message",
"type": ["const std::string_view"],
"const": true,
"brief_description": "Returns a string view to the message."
},
"saw-error-get_category": {
"id": "saw-error-get_category",
"name": "get_category",
"type": ["const std::string_view"],
"const": true,
"brief_description": "Returns a view describing which error this is.",
"detailed_description": [
["Looked up in the registry. This, not the code, is the identity which means the same thing in another process."]
]
},
"saw-error-failed": {
"id": "saw-error-failed",
"name": "failed",
"type": ["bool"],
"const": true,
"brief_description": "Checks if it is an error at all, since the code zero is reserved for no error."
},
"saw-error-is_critical": {
"id": "saw-error-is_critical",
"name": "is_critical",
"type": ["bool"],
"const": true,
"brief_description": "Checks if the error is critical."
},
"saw-error-is_recoverable": {
"id": "saw-error-is_recoverable",
"name": "is_recoverable",
"type": ["bool"],
"const": true,
"brief_description": "Checks if the error is recoverable."
},
"saw-error-copy_error": {
"id": "saw-error-copy_error",
"name": "copy_error",
"type": ["error"],
"const": true,
"brief_description": "Replaces the copy constructor, so copying an error is always explicit.",
"detailed_description": [
["If copying the message runs out of memory, the copy keeps the code and gets a static message instead of failing."]
]
},
"saw-error-get_id": {
"id": "saw-error-get_id",
"name": "get_id",
"type": ["error::code"],
"const": true,
"brief_description": "Returns the code."
},
"saw-error-is_type": {
"id": "saw-error-is_type",
"name": "is_type",
"type": ["bool"],
"const": true,
"brief_description": "Checks whether this error is of a given kind.",
"detailed_description": [
["The way to branch on an error. Comparing codes directly only works inside one process."]
],
"templates": [
{"name": "T", "kind": "type", "brief_description": "An error tag struct, e.g. err::not_found."}
],
"examples": [
{
"title": "Branching on the kind of failure",
"language": "cpp",
"code": "auto eov = srv.receive(dat_id);\nif(eov.is_error()){\n\tauto& err = eov.get_error();\n\tif(err.is_type<err::not_found>()){\n\t\t/// Nothing stored under that id yet.\n\t\treturn make_void();\n\t}\n\treturn std::move(err);\n}\n"
}
]
}
},
"notes": [
"Copy is forbidden; use copy_error when a second instance is genuinely needed."
]
}
|