exceptions.hpp
8.8 KB
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/*************************************************************************
*
* REALM CONFIDENTIAL
* __________________
*
* [2011] - [2015] Realm Inc
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Realm Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Realm Incorporated
* and its suppliers and may be covered by U.S. and Foreign Patents,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Realm Incorporated.
*
**************************************************************************/
#ifndef REALM_EXCEPTIONS_HPP
#define REALM_EXCEPTIONS_HPP
#include <stdexcept>
#include <realm/util/features.h>
namespace realm {
/// Thrown by various functions to indicate that a specified table does not
/// exist.
class NoSuchTable: public std::exception {
public:
const char* what() const noexcept override;
};
/// Thrown by various functions to indicate that a specified table name is
/// already in use.
class TableNameInUse: public std::exception {
public:
const char* what() const noexcept override;
};
// Thrown by functions that require a table to **not** be the target of link
// columns, unless those link columns are part of the table itself.
class CrossTableLinkTarget: public std::exception {
public:
const char* what() const noexcept override;
};
/// Thrown by various functions to indicate that the dynamic type of a table
/// does not match a particular other table type (dynamic or static).
class DescriptorMismatch: public std::exception {
public:
const char* what() const noexcept override;
};
/// The \c FileFormatUpgradeRequired exception can be thrown by the \c
/// SharedGroup constructor when opening a database that uses a deprecated file
/// format, and the user has indicated he does not want automatic upgrades to
/// be performed. This exception indicates that until an upgrade of the file
/// format is performed, the database will be unavailable for read or write
/// operations.
class FileFormatUpgradeRequired: public std::exception {
public:
const char* what() const noexcept override;
};
/// Thrown when memory can no longer be mapped to. When mmap/remap fails.
class AddressSpaceExhausted: public std::runtime_error {
public:
AddressSpaceExhausted(const std::string& msg);
/// runtime_error::what() returns the msg provided in the constructor.
};
/// The \c LogicError exception class is intended to be thrown only when
/// applications (or bindings) violate rules that are stated (or ought to have
/// been stated) in the documentation of the public API, and only in cases
/// where the violation could have been easily and efficiently predicted by the
/// application. In other words, this exception class is for the cases where
/// the error is due to incorrect use of the public API.
///
/// This class is not supposed to be caught by applications. It is not even
/// supposed to be considered part of the public API, and therefore the
/// documentation of the public API should **not** mention the \c LogicError
/// exception class by name. Note how this contrasts with other exception
/// classes, such as \c NoSuchTable, which are part of the public API, and are
/// supposed to be mentioned in the documentation by name. The \c LogicError
/// exception is part of Realm's private API.
///
/// In other words, the \c LogicError class should exclusively be used in
/// replacement (or in addition to) asserts (debug or not) in order to
/// guarantee program interruption, while still allowing for complete
/// test-cases to be written and run.
///
/// To this effect, the special `CHECK_LOGIC_ERROR()` macro is provided as a
/// test framework plugin to allow unit tests to check that the functions in
/// the public API do throw \c LogicError when rules are violated.
///
/// The reason behind hiding this class from the public API is to prevent users
/// from getting used to the idea that "Undefined Behaviour" equates a specific
/// exception being thrown. The whole point of properly documenting "Undefined
/// Behaviour" cases is to help the user know what the limits are, without
/// constraining the database to handle every and any use-case thrown at it.
///
/// FIXME: This exception class should probably be moved to the `_impl`
/// namespace, in order to avoid some confusion.
class LogicError: public std::exception {
public:
enum ErrorKind {
string_too_big,
binary_too_big,
table_name_too_long,
column_name_too_long,
table_index_out_of_range,
row_index_out_of_range,
column_index_out_of_range,
string_position_out_of_range,
link_index_out_of_range,
bad_version,
illegal_type,
/// Indicates that an argument has a value that is illegal in combination
/// with another argument, or with the state of an involved object.
illegal_combination,
/// Indicates a data type mismatch, such as when `Table::find_pkey_int()` is
/// called and the type of the primary key is not `type_Int`.
type_mismatch,
/// Indicates that two involved tables are not in the same group.
group_mismatch,
/// Indicates that an involved descriptor is of the wrong kind, i.e., if
/// it is a subtable descriptor, and the function requires a root table
/// descriptor.
wrong_kind_of_descriptor,
/// Indicates that an involved table is of the wrong kind, i.e., if it
/// is a subtable, and the function requires a root table, or if it is a
/// free-standing table, and the function requires a group-level table.
wrong_kind_of_table,
/// Indicates that an involved accessor is was detached, i.e., was not
/// attached to an underlying object.
detached_accessor,
/// Indicates that a specified row index of a target table (a link) is
/// out of range. This is used for disambiguation in cases such as
/// Table::set_link() where one specifies both a row index of the origin
/// table, and a row index of the target table.
target_row_index_out_of_range,
// Indicates that an involved column lacks a search index.
no_search_index,
/// Indicates that a modification was attempted that would have produced a
/// duplicate primary value.
unique_constraint_violation,
/// User attempted to insert null in non-nullable column
column_not_nullable,
/// Group::open() is called on a group accessor that is already in the
/// attached state. Or Group::open() or Group::commit() is called on a
/// group accessor that is managed by a SharedGroup object.
wrong_group_state,
/// No active transaction on a particular SharedGroup object (e.g.,
/// SharedGroup::commit()), or the active transaction on the SharedGroup
/// object is of the wrong type (read/write), or an attampt was made to
/// initiate a new transaction while one is already in progress on the
/// same SharedGroup object.
wrong_transact_state,
/// Attempted use of a continuous transaction through a SharedGroup
/// object with no history. See Replication::get_history().
no_history,
/// Durability setting (as passed to the SharedGroup constructor) was
/// not consistent across the session.
mixed_durability,
/// History type (as specified by the Replication implementation passed
/// to the SharedGroup constructor) was not consistent across the
/// session.
mixed_history_type
};
LogicError(ErrorKind message);
const char* what() const noexcept override;
ErrorKind kind() const noexcept;
private:
ErrorKind m_kind;
};
// Implementation:
inline const char* NoSuchTable::what() const noexcept
{
return "No such table exists";
}
inline const char* TableNameInUse::what() const noexcept
{
return "The specified table name is already in use";
}
inline const char* CrossTableLinkTarget::what() const noexcept
{
return "Table is target of cross-table link columns";
}
inline const char* DescriptorMismatch::what() const noexcept
{
return "Table descriptor mismatch";
}
inline const char* FileFormatUpgradeRequired::what() const noexcept
{
return "Database upgrade required but prohibited";
}
inline AddressSpaceExhausted::AddressSpaceExhausted(const std::string& msg):
std::runtime_error(msg)
{
}
inline LogicError::LogicError(LogicError::ErrorKind kind):
m_kind(kind)
{
}
inline LogicError::ErrorKind LogicError::kind() const noexcept
{
return m_kind;
}
} // namespace realm
#endif // REALM_EXCEPTIONS_HPP